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/12/16 20:31] vladiusen:toolworks:docs:apparatus:operating [2023/01/14 13:13] (current) vladius
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([](FMyTrait Trait) Chain->Operate([](FMyTrait Trait)
Line 44: Line 44:
 available, excessive tasks not needed for that quantity won't be queued at all. available, excessive tasks not needed for that quantity won't be queued at all.
  
-==== Argument Delivery ====+==== Dependency Injection ====
  
 One great thing about operating is that the function arguments are actually resolved 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  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: +iterated subject, just specify the Subject handle in the very declaration of the routine:<code cpp>
-<code cpp>+
 Chain->Operate([](FSubjectHandle Subject, FMyTrait Trait) Chain->Operate([](FSubjectHandle Subject, FMyTrait Trait)
 { {
Line 56: Line 55:
 </code> </code>
  
-This, of course, has to match the solidity of the chain. So for a solid chain this would be: +This, of course, has to match the solidity of the chain. So for a solid chain this would be:<code cpp>
-<code cpp>+
 SolidChain->Operate([](FSolidSubjectHandle Subject, FMyTrait& Trait) SolidChain->Operate([](FSolidSubjectHandle Subject, FMyTrait& Trait)
 { {
Line 64: Line 62:
 </code> </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>
  • en/toolworks/docs/apparatus/operating.1639675891.txt.gz
  • Last modified: 2021/12/16 20:31
  • by vladius