Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MotionPtr< T > Class Template Reference

A shared_ptr for MotionCommands; provides allocation and access to a MotionCommand, ensuring mutually exclusive access and scope-based deallocation. More...

#include <MotionPtr.h>

Inheritance diagram for MotionPtr< T >:

Detailed Description

template<class T>
class MotionPtr< T >

A shared_ptr for MotionCommands; provides allocation and access to a MotionCommand, ensuring mutually exclusive access and scope-based deallocation.

The MotionPtr class performs several jobs:

  • Maintain a reference to the enveloping shared memory region, via SharedObject
  • Access to object within a shared memory region, enforcing mutual exclusion via MMAccessor

The first point means that even if the motion is removed from the motion manager or dereferenced by an external source, your MotionPtr can still access the motion without error. Further, since the motion's MC_ID is stored in the motion, user code can test whether a motion is currently active or not. A corollary is that when this class goes out of scope, the memory region will also be dereferenced, preventing leaks. To enforce this more rigidly, if the MotionPtr detects that the memory region it is dereferencing is only referenced by the MotionManager, it will remove the motion from the MotionManager as well.

The second job addresses the concern that the Motion process may be querying the motion for output values while you're in the middle of updating the motion command's parameters. By overloading operator-> to return an MMAccessor, each access to the motion is protected by a mutual exclusion lock for the scope of access. Note that if you want to maintain a lock over several lines (for either performance or because the motion is left in a bad state between the calls), then you can use MarkScope to maintain the lock:

  MotionPtr<Foo> foo;
  foo->bar(); // a lock is obtained for the duration of this call
  foo->tweak(); // a second lock is obtained for this call

Alternatively:

  MotionPtr<Foo> foo;
  MarkScope lockfoo(foo); // a lock is obtained until 'lockfoo' goes out of scope
  foo->bar(); // the lock is maintained across these calls...
  foo->tweak();

The motion in MotionPtr is always "valid", and will be allocated using the templated motion's default constructor at the first access. If you wish to call a different constructor for the motion, you can pass a SharedObject created with the custom constructor calls to either MotionPtr's constructor or using operator=:

  MotionPtr<Foo> foo; // technically, no Foo has been allocated yet, but that's transparent
  foo->bar(); // first access, now the allocation actually occurs using default constructor
  foo = SharedObject<Foo>(1,2,4); // replacing the motion, this one constructed by Foo(1,2,4)
  
  MotionPtr<Foo> foo2(SharedObject<Foo>(8,16,32)); // use motion initialized by Foo(8,16,32)

You can share a motion between multiple MotionPtr instances, thanks to reference counting performed on the underlying memory region. When a SharedObjects, or another MotionPtrs, is assigned to a MotionPtr, a shallow copy is performed internally, so they all reference a common motion command:

  // ...continuing previous sample
  foo = foo2; // now foo and foo2 both refer to the Foo(8,16,32) instance

One advanced feature is that motions can have their memory region reset between activations by calling retain(false). If motions are not retained, this means that if the motion is removed from the motion manager, the MotionPtr will release its reference to the memory region. If the motion is accessed again thereafter, a new one will be created. Note that it is only a reference counting operation: if external references to the unretained motion remain, the original motion will survive, it just won't be accessible by this MotionPtr anymore unless reassigned.

Another advanced technique is if you really want to "leak" a motion, such as a self-pruning motion to restore some state as the behavior exits, or if another behavior holds only a MC_ID for the motion (thus there is no explicit reference to the underlying memory region), then you can extract the motion by:

  MotionPtr<Foo> foo; // motion you want to extract
  SharedObject<Foo> tmp = foo; // make a new reference to the region
  foo.clear() // drop foo's reference now
  // SharedObject will still dereference foo's memory region as it leaves this scope,
  // but assuming the motion is actually active, the motion manager holds a reference, so the
  // motion will survive (otherwise the memory will still be released as usual)

However, ideally MotionPtrs should be used for extended shared access to a motion (instead of sharing just the MC_ID). And if you are adding a "dangling" motion during exit, you should just call motman->addPrunableMotion directly with a SharedObject instead of using this class.

Definition at line 88 of file MotionPtr.h.

List of all members.

Public Member Functions

 MotionPtr ()
 Constructor, defaults to an empty SharedObject instance and will retain the allocation once it is created.
 MotionPtr (const SharedObject< T > obj)
 Constructor, adopts a reference to obj, and will retain the reference between additions to the motion manager.
 ~MotionPtr ()
 Destructor, if this holds the last non-motion manager reference to the motion, removes it from the motion manager.
 operator const SharedObject< T > & () const
 Automatically exposes the underlying shared object so you can pass it to SharedObject-based functions (e.g. BehaviorBase::addMotion() or MotionManager::addPersistentMotion()).
 operator MMAccessor< T > () const
 Automatically create MMAccessor instance for mutual-exclusion access.
MMAccessor< T > operator-> () const
 Forward smart-pointer style access to MMAccessor; this is the secret to one-line locking.
MMAccessor< T > operator* () const
 Forward smart-pointer style access to MMAccessor, just for completeness vs. operator->, which is what you'll want to use.
MotionPtroperator= (const SharedObject< T > &obj)
 Reassigns the motion reference; henceforth shall share the region with obj (shallow copy).
MotionPtroperator= (const MotionPtr &wr) const
 Reassigns the motion reference; henceforth shall share the region with wr (shallow copy).
virtual MotionManager::MC_ID getID () const
 Returns the motion command ID associated with the motion, or MotionManager::invalid_MC_ID if the motion is not allocated or otherwise not registered with the motion manager.
void clear ()
 Removes the reference to the current motion memory region.
bool allocated () const
 Returns true if the motion is non-NULL.
bool active () const
 Returns true if the motion is registered with the motion manager (i.e. it is both allocated and has a valid MC_ID).
bool retain () const
 Returns retained.
void retain (bool r)
 Sets retained.

Protected Member Functions

virtual void useResource (Data &)
 marks the resource as in use
virtual void releaseResource (Data &)
 releases the resource
virtual void processEvent (const EventBase &event)
 We only listen for motion deactivate events if not retained, so if we get a call here we should clear the reference.

Protected Attributes

SharedObject< T > mcObj
 Maintains the reference to the motion's shared memory region.
std::stack< MotionManager::MC_IDcheckouts
 Retains a history of useResource() calls, to be released by matching releaseResource() calls.
bool retained
 If false, clears the motion instance each time it is removed from the motion manager, and then recreate it if a future access occurs.

Constructor & Destructor Documentation

template<class T>
MotionPtr< T >::MotionPtr (  )  [explicit]

Constructor, defaults to an empty SharedObject instance and will retain the allocation once it is created.

Definition at line 11 of file MotionPtr.h.

template<class T>
MotionPtr< T >::MotionPtr ( const SharedObject< T >  obj  ) 

Constructor, adopts a reference to obj, and will retain the reference between additions to the motion manager.

Definition at line 13 of file MotionPtr.h.

template<class T>
MotionPtr< T >::~MotionPtr (  ) 

Destructor, if this holds the last non-motion manager reference to the motion, removes it from the motion manager.

Definition at line 15 of file MotionPtr.h.


Member Function Documentation

template<class T>
bool MotionPtr< T >::active (  )  const

Returns true if the motion is registered with the motion manager (i.e. it is both allocated and has a valid MC_ID).

Definition at line 84 of file MotionPtr.h.

template<class T>
bool MotionPtr< T >::allocated (  )  const

Returns true if the motion is non-NULL.

Definition at line 81 of file MotionPtr.h.

Referenced by MotionPtr< HeadPointerMC >::processEvent().

template<class T>
void MotionPtr< T >::clear (  ) 

Removes the reference to the current motion memory region.

A new one will be created with the default constructor if a future access is attempted.

Definition at line 78 of file MotionPtr.h.

Referenced by LookAtMarkers::Search::doEvent().

template<class T>
virtual MotionManager::MC_ID MotionPtr< T >::getID (  )  const [virtual]

Returns the motion command ID associated with the motion, or MotionManager::invalid_MC_ID if the motion is not allocated or otherwise not registered with the motion manager.

Definition at line 70 of file MotionPtr.h.

template<class T>
MotionPtr< T >::operator const SharedObject< T > & (  )  const

Automatically exposes the underlying shared object so you can pass it to SharedObject-based functions (e.g. BehaviorBase::addMotion() or MotionManager::addPersistentMotion()).

Definition at line 30 of file MotionPtr.h.

template<class T>
MotionPtr< T >::operator MMAccessor< T > (  )  const

Automatically create MMAccessor instance for mutual-exclusion access.

This lets you assign the MotionPtr to a MMAccessor, so that the lock persists under the new scope and name. You could also use MarkScope with the MotionPtr.

Definition at line 38 of file MotionPtr.h.

template<class T>
MMAccessor<T> MotionPtr< T >::operator* (  )  const

Forward smart-pointer style access to MMAccessor, just for completeness vs. operator->, which is what you'll want to use.

This is actually a little syntactically wrong, because operator*() should return a reference vs. operator->'s pointer, but then we would lose the locking guarantee.

Definition at line 49 of file MotionPtr.h.

template<class T>
MMAccessor<T> MotionPtr< T >::operator-> (  )  const

Forward smart-pointer style access to MMAccessor; this is the secret to one-line locking.

Keep in mind you can use MarkScope with the MotionPtr to retain the lock over the course of multiple accesses

Definition at line 45 of file MotionPtr.h.

template<class T>
MotionPtr& MotionPtr< T >::operator= ( const MotionPtr< T > &  wr  )  const

Reassigns the motion reference; henceforth shall share the region with wr (shallow copy).

Internal reference counting by the shared memory region will keep everything happy :)

Definition at line 67 of file MotionPtr.h.

template<class T>
MotionPtr& MotionPtr< T >::operator= ( const SharedObject< T > &  obj  ) 

Reassigns the motion reference; henceforth shall share the region with obj (shallow copy).

Internal reference counting by the shared memory region will keep everything happy :)

Definition at line 53 of file MotionPtr.h.

template<class T>
virtual void MotionPtr< T >::processEvent ( const EventBase event  )  [protected, virtual]

We only listen for motion deactivate events if not retained, so if we get a call here we should clear the reference.

Implements EventListener.

Definition at line 118 of file MotionPtr.h.

template<class T>
virtual void MotionPtr< T >::releaseResource ( Data d  )  [protected, virtual]

releases the resource

Implements Resource.

Definition at line 111 of file MotionPtr.h.

template<class T>
void MotionPtr< T >::retain ( bool  r  ) 

Sets retained.

Definition at line 90 of file MotionPtr.h.

template<class T>
bool MotionPtr< T >::retain (  )  const

Returns retained.

Definition at line 87 of file MotionPtr.h.

template<class T>
virtual void MotionPtr< T >::useResource ( Data d  )  [protected, virtual]

marks the resource as in use

Implements Resource.

Definition at line 103 of file MotionPtr.h.


Member Data Documentation

template<class T>
std::stack<MotionManager::MC_ID> MotionPtr< T >::checkouts [protected]

Retains a history of useResource() calls, to be released by matching releaseResource() calls.

This solves the problem of removing a motion while it is locked... the removal clears the ID value in mcObj, thus we need to store it here so we can checkin (unlock) the motion later. Using a stack lets us handle recursively re-adding the motion and receiving a new ID while still locked under the original ID.

Definition at line 141 of file MotionPtr.h.

template<class T>
SharedObject<T> MotionPtr< T >::mcObj [protected]

Maintains the reference to the motion's shared memory region.

Definition at line 135 of file MotionPtr.h.

Referenced by MotionPtr< HeadPointerMC >::processEvent().

template<class T>
bool MotionPtr< T >::retained [protected]

If false, clears the motion instance each time it is removed from the motion manager, and then recreate it if a future access occurs.

If true, the reference on mcObj will be retained between additions to the motion manager, which is the default behavior.

Definition at line 145 of file MotionPtr.h.


The documentation for this class was generated from the following file:

Tekkotsu v5.1CVS
Generated Mon May 9 04:59:13 2016 by Doxygen 1.6.3