AGX Dynamics 2.42.3.0
Loading...
Searching...
No Matches
StepEventCallback.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#pragma once
18
19#include <agxSDK/Simulation.h>
20
21#include <array>
22
23namespace agxUtil
24{
46 {
47 public:
62 {
68 : activation( (agxSDK::StepEventListener::ActivationMask)activation )
69 {
70 }
71
73 };
74
75 public:
82 static void uninitialize( agxSDK::Simulation* simulation );
83
96 static void removeMe( agxSDK::Simulation* simulation );
97
104 template<typename FuncT, typename... Args>
105 static void preCollide( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args );
106
113 template<typename FuncT, typename... Args>
114 static void pre( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args );
115
122 template<typename FuncT, typename... Args>
123 static void post( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args );
124
131 template<typename FuncT, typename... Args>
132 static void last( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args );
133
148 template<typename FuncT, typename... Args>
149 static void callAt( agx::Real timeStamp,
150 DefaultIsPreCollide callbackType,
151 FuncT&& callback,
152 agxSDK::Simulation* simulation,
153 Args&&... args );
154
164 template<typename FuncT, typename... Args>
165 static void callFor( agx::Real seconds,
166 DefaultIsPreCollide callbackType,
167 FuncT&& callback,
168 agxSDK::Simulation* simulation,
169 Args&&... args );
170
171 protected:
176
180 virtual void addNotification() override;
181
185 virtual void removeNotification() override;
186
187 virtual void preCollide( const agx::TimeStamp& t ) override;
188 virtual void pre( const agx::TimeStamp& t ) override;
189 virtual void post( const agx::TimeStamp& t ) override;
190 virtual void last( const agx::TimeStamp& t ) override;
191
192 private:
193 enum CallbackType
194 {
195 PRE_COLLIDE_TYPE,
196 PRE_TYPE,
197 POST_TYPE,
198 LAST_TYPE,
199 NUM_CALLBACK_TYPES
200 };
201
207 using Callback = std::function<void()>;
208 struct TimedCallbackData
209 {
210 Callback callback{};
211 CallbackType callbackType = PRE_COLLIDE_TYPE;
212 agx::Real startTime = -1.0;
213 agx::Real endTime = -1.0;
214 };
215
216 using StepCallbackVector = std::vector<Callback>;
217 using TimedCallbackVector = std::vector<TimedCallbackData>;
218 using StepEventCallbackRef = agx::ref_ptr<StepEventCallback>;
220 using StepCallbacks = std::array<StepCallbackVector, (size_t)NUM_CALLBACK_TYPES>;
221 using TimedCallbacks = std::array<TimedCallbackVector, (size_t)NUM_CALLBACK_TYPES>;
222
223
224 struct InternalState
225 {
226 enum Flag : agx::UInt32
227 {
228 EXECUTING_CALLBACKS = 1 << 0,
229 REMOVE_CURRENT_REQUEST = 1 << 1,
230 };
231 using Flags = agx::BitState<Flag, std::underlying_type_t<Flag>>;
232 Flags flags;
233
234 CallbackType currCallbackType = NUM_CALLBACK_TYPES;
235 StepCallbackVector deferredStepCallbacks;
236 TimedCallbackVector deferredTimedCallbacks;
237
238 inline InternalState()
239 : flags()
240 {
241 }
242
243 inline bool removeRequestedAndResetState()
244 {
245 const auto removeRequested = flags.Is( REMOVE_CURRENT_REQUEST );
246 flags.update( REMOVE_CURRENT_REQUEST, false );
247 return removeRequested;
248 }
249
250 inline bool isExecutingCallbacks( CallbackType callbackType ) const
251 {
252 return currCallbackType != NUM_CALLBACK_TYPES && callbackType == currCallbackType;
253 }
254
255 inline void begin( CallbackType callbackType )
256 {
257 agxAssert( currCallbackType == NUM_CALLBACK_TYPES );
258 agxAssert( !flags.Is( EXECUTING_CALLBACKS ) );
259 agxAssert( deferredStepCallbacks.empty() );
260 agxAssert( deferredTimedCallbacks.empty() );
261 flags.update( EXECUTING_CALLBACKS, true );
262 currCallbackType = callbackType;
263 }
264
265 inline void end( StepCallbackVector& stepCallbacks, TimedCallbackVector& timedCallbacks )
266 {
267 stepCallbacks.insert( stepCallbacks.end(),
268 deferredStepCallbacks.begin(),
269 deferredStepCallbacks.end() );
270 deferredStepCallbacks.clear();
271
272 timedCallbacks.insert( timedCallbacks.end(),
273 deferredTimedCallbacks.begin(),
274 deferredTimedCallbacks.end() );
275 deferredTimedCallbacks.clear();
276
277 flags.update( EXECUTING_CALLBACKS, false );
278 currCallbackType = NUM_CALLBACK_TYPES;
279 }
280 };
281
282 private:
287 static StepEventCallback& getOrCreate( agxSDK::Simulation& simulation );
288
293 static bool hasInstance( const agxSDK::Simulation* simulation );
294
301 static void registerCallback( const Callback& callback,
302 CallbackType callbackType,
303 agxSDK::Simulation* simulation );
304
314 static void registerCallback( agx::Real startTime,
315 agx::Real endTime,
316 DefaultIsPreCollide callbackType,
317 const Callback& callback,
318 agxSDK::Simulation* simulation );
319
320 private:
325 StepEventCallback();
326
330 void executeCallbacks( const agx::TimeStamp& t, CallbackType callbackType );
331
332 private:
333 static InstanceType s_instances;
334 StepCallbacks m_stepCallbacks;
335 TimedCallbacks m_timedCallbacks;
336 InternalState m_state;
337 };
338
339 template<typename FuncT, typename... Args>
340 void StepEventCallback::preCollide( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args )
341 {
342 if ( simulation == nullptr )
343 return;
344
345 registerCallback( std::bind( std::forward<FuncT>( callback ),
346 simulation,
347 std::forward<Args>( args )... ),
348 PRE_COLLIDE_TYPE,
349 simulation );
350 }
351
352 template<typename FuncT, typename... Args>
353 void StepEventCallback::pre( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args )
354 {
355 if ( simulation == nullptr )
356 return;
357
358 registerCallback( std::bind( std::forward<FuncT>( callback ),
359 simulation,
360 std::forward<Args>( args )... ),
361 PRE_TYPE,
362 simulation );
363 }
364
365 template<typename FuncT, typename... Args>
366 void StepEventCallback::post( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args )
367 {
368 if ( simulation == nullptr )
369 return;
370
371 registerCallback( std::bind( std::forward<FuncT>( callback ),
372 simulation,
373 std::forward<Args>( args )... ),
374 POST_TYPE,
375 simulation );
376 }
377
378 template<typename FuncT, typename... Args>
379 void StepEventCallback::last( FuncT&& callback, agxSDK::Simulation* simulation, Args&&... args )
380 {
381 if ( simulation == nullptr )
382 return;
383
384 registerCallback( std::bind( std::forward<FuncT>( callback ),
385 simulation,
386 std::forward<Args>( args )... ),
387 LAST_TYPE,
388 simulation );
389 }
390
391 template<typename FuncT, typename... Args>
393 DefaultIsPreCollide callbackType,
394 FuncT&& callback,
395 agxSDK::Simulation* simulation,
396 Args&&... args )
397 {
398 registerCallback( timeStamp,
399 timeStamp,
400 callbackType,
401 std::bind( std::forward<FuncT>( callback ),
402 simulation,
403 std::forward<Args>( args )... ),
404 simulation );
405 }
406
407 template<typename FuncT, typename... Args>
409 DefaultIsPreCollide callbackType,
410 FuncT&& callback,
411 agxSDK::Simulation* simulation,
412 Args&&... args )
413 {
414 if ( simulation == nullptr )
415 return;
416
417 registerCallback( simulation->getTimeStamp(),
418 simulation->getTimeStamp() + seconds,
419 callbackType,
420 std::bind( std::forward<FuncT>( callback ),
421 simulation,
422 std::forward<Args>( args )... ),
423 simulation );
424 }
425}
#define AGXPHYSICS_EXPORT
Simulation is a class that bridges the collision space agxCollide::Space and the dynamic simulation s...
Definition: Simulation.h:131
agx::Real getTimeStamp() const
Definition: Simulation.h:1896
Derive from this class to implement a listener for simulation step events.
ActivationMask
Defines the event states for which a listener will be activated, a mask can be bitwise OR:ed from the...
@ PRE_COLLIDE
Triggered just BEFORE a simulation step is taken.
Helper to use lambdas as preCollide, pre, post and last step events.
virtual void addNotification() override
Add notification callback.
static void removeMe(agxSDK::Simulation *simulation)
Call this from within a callback to be removed from receiving any more calls.
virtual ~StepEventCallback()
Reference counted object, protected destructor.
static void last(FuncT &&callback, agxSDK::Simulation *simulation, Args &&... args)
Register a last step event callback.
static void preCollide(FuncT &&callback, agxSDK::Simulation *simulation, Args &&... args)
Register a pre-collide step event callback.
static void pre(FuncT &&callback, agxSDK::Simulation *simulation, Args &&... args)
Register a pre step event callback.
virtual void last(const agx::TimeStamp &t) override
Called after a step is taken in the simulation Implement this method in the derived class to get call...
virtual void pre(const agx::TimeStamp &t) override
Called before a step is taken in the simulation Implement this method in the derived class to get cal...
virtual void post(const agx::TimeStamp &t) override
Called after a step is taken in the simulation Implement this method in the derived class to get call...
static void callAt(agx::Real timeStamp, DefaultIsPreCollide callbackType, FuncT &&callback, agxSDK::Simulation *simulation, Args &&... args)
Register callback to be called at a given simulation time.
static void post(FuncT &&callback, agxSDK::Simulation *simulation, Args &&... args)
Register a post step event callback.
virtual void removeNotification() override
Remove notification callback - will unregister this from the static instances.
virtual void preCollide(const agx::TimeStamp &t) override
Called before collision detection is performed in the simulation Implement this method in the derived...
static void uninitialize(agxSDK::Simulation *simulation)
Removes internal step event listener from the simulation (if created).
static void callFor(agx::Real seconds, DefaultIsPreCollide callbackType, FuncT &&callback, agxSDK::Simulation *simulation, Args &&... args)
Executes given callback in seconds seconds from the current time stamp of the given simulation.
Inheritance with partial specialization due to bug with ref_ptr containers.
Smart pointer for handling referenced counted objects.
Definition: ref_ptr.h:30
#define agxAssert(expr)
Definition: debug.h:143
Flags
Flags for specifying what is enabled in the debug rendering system.
Definition: RenderManager.h:57
The agxSDK namespace contain classes to bridge the collision detection system and the dynamical simul...
Definition: Constraint.h:31
The agxUtil namespace contain classes and methods for utility functionality.
uint32_t UInt32
Definition: Integer.h:32
LinearProbingHashSetImplementation< KeyT, HashT >::iterator end(LinearProbingHashSetImplementation< KeyT, HashT > &set)
double Real
Definition: Real.h:41
LinearProbingHashSetImplementation< KeyT, HashT >::iterator begin(LinearProbingHashSetImplementation< KeyT, HashT > &set)
agx::Real TimeStamp
Definition: TimeStamp.h:26
Used as argument in timed callbacks (callAt, callFor et al.) where it might not matter as much when t...
DefaultIsPreCollide(int activation=agxSDK::StepEventListener::PRE_COLLIDE)
Construct given activation mask, default PRE_COLLIDE.