Events Documentation

When constructing a scene in imstk a lot of work is done by hooking up to the correct events posted by the various parts of the architecture, yet while a lot of components inherit from EventObject there seems to be very little documentation on the classes which objects actually post what events and what they mean. Even having a section in the classes main documentation would be helpful.

But additionally as these are very distributed throughout the system having a general documentation on the classes that post events, and what when to use specific ones would be very helpful.

For example right now i am trying to discover how do detect when the simulation is ending, and really only a Find all references on the End symbol reveals that it’s only the abstractVtkViewer that is posting this event.

Or am i just missing a document somewhere ?

I can see a use for start and stop events for simulation manager, we had them at one point for ThreadObjects back when we had those.

The simulation manager is currently synchronous. So you should know when you call start. And when you return from start, the simulation has ended.

This is not just start/end for example, besides digging through the code there is no documentation on what objects post which specific events.

With regards to start/stop in the simulationmanager there is an unknown amount of time that passes before the loops starts up, waitForInit() for example, and same at the end as the join() is executed and maybe destructors are called.

Looking forward to maybe moving to a more component based approach it helps when the components are able to determine in which phase of starting/running/shutting down the system is.

I posted an MR that adds start/end signals to the simulation manager

Alright, merged. Yeah, some post initialize and pre join/cleanup callbacks could be handy. I suppose it gives you, at least, one level of initialize and cleanup order. To guarantee whatever it is you want to do in that function is called after initialization or before cleanup.

I would often recommend extending classes to provide more elaborate initialization and cleanup order. (most commonly that would be SceneManager or Scene). If you’re trying to create an order between two objects not in the same level of a member hierarchy, you might be doing something wrong, or just not encouraged. For instance, modules are, in part, designed to be independent from each other. But nothings stopping one from making complex sync mechansims, flags, waits, while loops, and state checking between them. Or just implementing their own driver/SimulationManager.

I do like the idea of better documenting events. Looking at a few APIs.

  • VTK is fairly similar to our event system now. They use types as well. They provide a list of events in the majority of their in code documentation (ex: Additionally I have found you can just subscribe to all, then print the ids to see what it emits.

  • Unity provides no help on their events. But they do have examples. As far as I know.

  • I love how Qt does it. They provide a beautiful list of signals and slots with descriptions for each online. This is most easy for them because each signal and slot is a function definition. So they can just provide descriptions above the function. And when you go to type out a connection it goes like connect(sender, sender func, reciever, reciever func). So in intellisense you can float your mouse over that sender/signal func and see, that or look it up online. Also the function name tells a lot.

For us to do the same, such that there is a function definition that posts the event. And that same function is directly used when calling/filtering connect. We would need to store observer callbacks in the sender, by sender func instead of event type. I might expirement with this later. More extensible. Though I get the feeling I did when I first coded it.

What happens now is the sender stores each observer/subscriber callback by event type, so when an event of type X is posted, only the observers that are listening to that type, are called.

I wasn’t suggesting to change the way events are implemented it seems workable for now, but right now imstk has a lot of parts and beside the examples its hard to see how these parts should be put together. I’m missing this ( for imstk.

As you said one can always implement your own sim manager but my guess is that there are going to be a lot more people using the built in functionality than writing their own. If we can give them a good framework I think it’s helpful.

I realize i’m used to doing things a certain way, oss took a lot of inspiration from the unity model of constructing a scene. Looking at osteotomy a lot of information and work sits outside of the actual simulation parts, with OSS as well as unity a lot of these pieces are on code that participates in the simulation loop. I don’t know if that is a result of the object/component model or if its a consequence of loading the scene rather than constructing it programmatically. If you look all the work is done on gameobjects or things held by gameobjects.

This on the side but the issue with this approach and with some Qt code as well is that it becomes really hard to reason about order and structure. once the code goes beyond a certain size a lose event or (signals/slot) connect model can get so tangled up that tracking any kind of cause and effect chain is a pita

In terms of adding functionality here’s your options:

If you want to add function to the scene.

  • If order doesn’t matter:
    • Extend SceneObject and override and implement init and/or update.
  • If order does matter:
    • Extend Scene and override init and/or advance to provide that order for a scene.
  • There are also post/pre update callbacks.

If you want to add function to the simulation manager.

  • If order doesn’t matter:
    • Extend Module and override the initModule and updateModule call. You can put it in adaptive or sequential mode (akin to fixed update and update)
  • If order does matter:
    • Extend SimulationManager (or ModuleDriver, its base class) and override initModule and updateModule to provide that order of init and update for a SimulationManager.
    • I’m thinking we should probably also make the adaptive and sequential module update loop virtual functions so one could subclass SimulationManager and implement those. Or else they would need to reimplement the substep update loop if they extended.

That’s what we have. Hopefully it helps you figure out a nice solution. Idk all your requirements but maybe a MetricsModule would be nice? If you make it adaptive update will go render->[scene->metrics->scene->metrics->…]->render->[…].

We also have the TaskGraph, but that’s mostly for complex intermediate interactions between objects (interactions between mid updates of objects) which are only super useful for physics and debugging.

II think the SceneObject as the first customization point is a good idea but the fixed enums that are being used for type detection prevent this. As any local sceneobject anyone would want to write would have to modify the list in imstk proper if the type doesn’t fit the list. I can’t seem to find a lot of use of the type enums except for one check in the scene on Rigid but maybe visual studio is lying to me.

Additionally the SceneObject carries a lot of architecture that might not be needed so some functionality between the sceneObject and the entity would be great but that’s not essential

Privacy Notice