question

Tom S4 avatar image
0 Likes"
Tom S4 asked Jordan Johnson commented

Event Listening with Module SDK

This is a follow-up to a comment in my previous post. I am trying to listen to a shared resource's Entry and Exit from within a custom Acquire object I have.

https://answers.flexsim.com/questions/135257/custom-acquire-resource-activity-processflow-modul.html

I slightly modified the ReinforcementLearning::addDecisionListener() method. I made the following changes:

  1. Replaced DecisionEvent() with FlexSimEvent()
  2. Replaced this->holder with a parameter listenerObj (I am currently passing in my custom acquire object's holder)
void addEventListener(FlexSim::TreeNode* eventObject, const char* eventName, FlexSim::TreeNode* listenerObj)
{
   if (objectexists(eventObject)) 
   {
      // Find and select event
      EventBinding eventBinding;
      eventObject->objectAs(SimpleDataType)->enumerateEvents(&eventBinding);
      eventBinding.select(eventName);

      TreeNode* theNode = eventObject->objectAs(SimpleDataType)->assertEvent(&eventBinding);
      if (theNode) 
      {
         switch_activelisteners(theNode, 1);
         TreeNode* newListenerNode = nodeinsertinto(theNode);
         switch_activelisteners(newListenerNode, 1);
         switch_destroyonreset(newListenerNode, 1);
         nodeaddcouplingdata(newListenerNode, new FlexSim::FlexSimEvent(), 1);
         nodepoint(newListenerNode, listenerObj);
      }
   }
}

I am using this method as follows:

addEventListener(treenodeReferenceToResourceBlock, "OnExit", customAcquireObject->holder)

In the tree, I can see this successfully add a listener to OnExit. However, it looks different compared to, for example, the listener added by an Event Triggered Source block.

Using my code:

1675887405982.png

Using Event Triggered Source:

1675887414410.png


Am I doing this correctly?

Also, how can I hook into this listener and execute a function within my custom acquire block when this event fires?

FlexSim 23.0.1
processflowmodule sdkevent
1675887405982.png (36.0 KiB)
1675887414410.png (45.8 KiB)
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

1 Answer

Jordan Johnson avatar image
2 Likes"
Jordan Johnson answered Jordan Johnson commented

The place for your own code is to write a class that inherits FlexSimEvent, and then overrides the execute() method. Then, you attach your own listener in the place of FlexSimEvent. This is the pattern shown in the RL object's DecisionEvent; you'd write your own in a very similar way.

You can find the definition of DecisionEvent at MAIN:/project/library/ReinforcementLearning>behaviour/includeheader, at the end of the text. It messes with the time of the event in a way you don't need to do, but otherwise it's a good pattern for you to follow.

· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Tom S4 avatar image Tom S4 commented ·

Thanks, I think it might've finally clicked. This is what I'm thinking:

class CustomAcquire: public Acquire
{
   ... // activity stuff

   void addEventListener()
   {
       // my code above, with MyCustomEvent instead of FlexSimEvent
   } 
   
   class MyCustomEvent: public FlexSimEvent
   {
      MyCustomEvent(CustomAcquire* activity) {this->activity = activity;} // give event access to activity functions

      void execute()
      {
         // I believe params should be instance, activity, token
         CallPoint* callPoint = getListenerCallPoint();
         Variant p1 = callPoint->getParam(1);
         ... // 2, 3

         this->activity->doStuffWhenEventFires(p1, p2, p3);
      }
   }
}


0 Likes 0 ·
Jordan Johnson avatar image Jordan Johnson ♦♦ Tom S4 commented ·
At a glance, that looks right.
0 Likes 0 ·