en:toolworks:docs:apparatus:operating

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
en:toolworks:docs:apparatus:operating [2021/08/29 00:12] vladiusen:toolworks:docs:apparatus:operating [2023/01/14 13:13] (current) vladius
Line 1: Line 1:
 ====== Operating ====== ====== Operating ======
  
-The newer and more robust way of processing your chains is through the process called operating.+The newer and more robust way of handle your chains is through the process called operating.
  
 ===== C++ Workflow ===== ===== C++ Workflow =====
Line 7: Line 7:
 ==== Using a Lambda ==== ==== Using a Lambda ====
  
-You can easily operate on your chain via a C++ lambda and this is how you do it:+You can easily operate on your chain via a [[cpp>language/lambda|C++ lambda]] and this is how you do it:
 <code cpp> <code cpp>
-Chain->Operate([](const FChain::FCursor& Cursor, FMyTrait Trait)+Chain->Operate([](FMyTrait Trait)
 { {
     ...     ...
Line 15: Line 15:
 </code> </code>
  
-The type of cursor here must match the type of the chain used. 
 Note that you're not allowed to acquire a reference to the trait while processing a non-solid chain, only its copy. Note that you're not allowed to acquire a reference to the trait while processing a non-solid chain, only its copy.
 So in order to operate on a solid chain, you could do something like this: So in order to operate on a solid chain, you could do something like this:
  
 <code cpp> <code cpp>
-SolidChain->Operate([](const FSolidChain::FCursor& Cursor, FMyTrait& Trait)+SolidChain->Operate([](FMyTrait& Trait)
 { {
     ...     ...
Line 32: Line 31:
 Solid Chains also support a special type of operating - a multi-threaded one. Solid Chains also support a special type of operating - a multi-threaded one.
 The function to call is explicitly named with a ''Concurrently'' prefix and The function to call is explicitly named with a ''Concurrently'' prefix and
-accepts two more arguments: the number of tasks to utilize and the minimum number +accepts two more arguments: the maximum number of tasks to utilize and the minimum number 
-of slots (Entity places) per each such task. For example:+of slots per each such task. For example:
  
 <code cpp> <code cpp>
-SolidChain->OperateConcurrently([](const FSolidChain::FCursor& Cursor, FMyTrait& Trait)+SolidChain->OperateConcurrently([](FMyTrait& Trait)
 { {
     ...     ...
 }, 4, 32); }, 4, 32);
 +</code>
 +
 +The second parameter helps to also limit the number of tasks. If there are too little slots
 +available, excessive tasks not needed for that quantity won't be queued at all.
 +
 +==== Dependency Injection ====
 +
 +One great thing about operating is that the function arguments are actually resolved
 +and delivered automatically to your logic. For example, if you also modify the currently 
 +iterated subject, just specify the Subject handle in the very declaration of the routine:<code cpp>
 +Chain->Operate([](FSubjectHandle Subject, FMyTrait Trait)
 +{
 +    ...
 +});
 +</code>
 +
 +This, of course, has to match the solidity of the chain. So for a solid chain this would be:<code cpp>
 +SolidChain->Operate([](FSolidSubjectHandle Subject, FMyTrait& Trait)
 +{
 +    ...
 +});
 +</code>
 +
 +You can actually ask for different contextual information within the loop. For example:<code cpp>
 +Chain->Operate([](const FChain* Chain, const FChainCursor& Cursor, ISubjective* Subjective, FMyTrait Trait, UMyDetail* Detail)
 +{
 +    ...
 +});
 +</code>
 +
 +==== Current Iteration Index ====
 +
 +Just in case you need to know the number of the current iterated Slot (i.e. Subject's place within the chain), use the dedicated [[appi>struct_t_chain_1_1_f_cursor.html#a18005eddb3a624bdabb76475c3863751|GetChainSlotIndex()]] method of the corresponding Cursor type, which can also be delivered using the [[#argument_delivery|aforementioned means]]:<code cpp>
 +SolidChain->Operate([](FPlacementTrait& Placement, const FSolidChainCursor& Cursor)
 +{
 + Placement.Number = Cursor.GetChainSlotIndex();
 +});
 +</code>
 +
 +==== Stopping ====
 +
 +While conceptually not very clean it is sometime useful to stop the actual processing (iterating) of the chain
 +prematurely, manually. This can be easily accomplished with a dedicated [[appi>struct_t_chain.html#aec97fe73be3d6d9f4c279c7427ed99d6|method]].
 +
 +For example:<code cpp>
 +int32 Counter = 0;
 +Chain->Operate([&Counter](const FChain* Chain, FMyTrait Trait)
 +{
 +    if (Counter > 100)
 +    {
 +        Chain->StopIterating();
 +        // Return explicitly, so the counter doesn't get incremented on the current iteration:
 +        return;
 +    }
 +    Counter += Trait.Value;
 +});
 +</code>
 +
 +==== Direct Mechanism Operating ====
 +
 +The Operating simplification goes as far as actually Operating on a Mechanism directly, like so:<code cpp>
 +Mechanism->Operate([](FGlowing Glowing, FHelmet Helmet)
 +{
 +    ...
 +});
 +</code>
 +
 +This way the [[en:toolworks:docs:apparatus:filter|Filtering]] and the [[en:toolworks:docs:apparatus:enchaining|Enchaining]] is done automatically under the hood, deriving the necessary Components from the lambda arguments.
 +
 +You can of course supply the Filter specification explicitly, overriding it.
 +
 +So for example, if you want to specify an additional [[en:toolworks:docs:apparatus:trait|Trait]] and a [[en:toolworks:docs:apparatus:flag|Flagmark]] condition, do it like so:<code cpp>
 +Mechanism->Operate(FFilter::Make<FGlowing, FHelmet, FHero>(FM_Z), [](FGlowing Glowing, FHelmet Helmet)
 +{
 +    ...
 +});
 +</code>
 +
 +The direct Operating mode is smart enough to deduce the type of the Chain used within the Operating process, so if you specify a reference to a Trait and/or a Solid Subject handle in your arguments list, the technique will essentially produce a [[en:toolworks:docs:apparatus:solidity|Solid]] iterating:<code cpp>
 +Mechanism->Operate([](FSolidSubjectHandle Subject, FGlowing& Glowing, FHelmet& Helmet)
 +{
 +    ...
 +});
 +</code>
 +
 +You can still specify the Chain type explicitly as a first template argument to a method:<code cpp>
 +Mechanism->Operate<FSolidChain>([](FGlowing Glowing, FHelmet Helmet)
 +{
 +    // You logic within Solid semantics:
 +    ...
 +});
 +</code>
 +
 +Concurrency variants are also provided by the direct interface:<code cpp>
 +Mechanism->OperateConcurrently([](FSolidSubjectHandle Subject, FGlowing& Glowing, FHelmet& Helmet)
 +{
 +    ...
 +}, /*Maximum number of threads=*/4, /*Minimum number of Subjects=*/16);
 </code> </code>
  • en/toolworks/docs/apparatus/operating.1630185133.txt.gz
  • Last modified: 2021/08/29 00:12
  • by vladius