Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MMAccessor< MC_t > Class Template Reference

This class allows convenient ways of accessing a motion command. More...

#include <MMAccessor.h>


Detailed Description

template<class MC_t>
class MMAccessor< MC_t >

This class allows convenient ways of accessing a motion command.

Since MotionCommands must be checked out of the motion manager and then checked back in when they are done, this is a common source of errors, leading to deadlock. This class will check the motion out when it's created, and check it back in when it goes out of scope
It supports recursive checkin/checkouts.
Uses global motman

So, instead of doing things like this:

  YourMotionCommand* ymc = dynamic_cast<YourMotionCommand*>(motman->checkoutMotion(your_mc_id));
  //do 'stuff' with ymc, e.g.: ymc->rollOver();
  motman->checkinMotion(your_mc_id);

...which can be error prone in many regards - if 'stuff' returns without checking in, or you forget to check in, or you get lazy and leave it checked out longer than you should, which can cause general performance issues (or worse, deadlock) Using MMAccessor makes it much easier to solve these problems, and is easier to code:

  MMAccessor<YourMotionCommand> mma(your_mc_id);
  //do 'stuff' with mma, e.g.: mma->rollOver();

We can call a return at any point and the motion command will automatically be checked in, and since C++ guarrantees that the destructor of mma will be called, we don't have to worry about forgetting about it. We can limit the scope by placing {}'s around the segment in question:

  //pre-stuff
  {
    MMAccessor<YourMotionCommand> mma(your_mc_id);
    //do 'stuff' with mma, e.g.: mma->rollOver();
  }
  //post-stuff - has no knowledge of mma, out of its scope

And, for those astute enough to notice that the theoretical rollOver() function is called on MMAccessor when it's actually a member of YourMotionCommand, this is because MMAccessor behaves as a 'smart pointer', which overloads operator->() so it is fairly transparent to use.

In some cases, you may wish to access a prunable motion, but may be unsure of whether the motion is still alive. If it has been pruned, the MC_ID is no longer valid, and will not provide access to the motion. Worse, however, is that enough new motions have been created that the ID has been recycled and now refers to another, different, motion.

The solution to this requires two steps. First, you must retain the SharedObject you used to initially create the motion. This is required because if the MotionManager prunes the motion, it will dereference the memory region, and if there are no other references to the region, it will be deallocated, destroying the data. Second, you pass this SharedObject to the MMAccessor constructor as shown:

  SharedObject<YourMC> yourmc;
  // ... stuff ... if yourmc was added to MotionManager, it may or may not still be active
  MMAccessor<YourMC> your_acc(*yourmc); // doesn't matter!
  // your_acc now provides no-op access if not in MotionManager, checks it out if it is

This guarantees safe access regardless to the current status of the motion. (Note that you can also just listen for the (EventBase::motmanEGID, MC_ID, EventBase::deactivateETID) event to be notified when a motion is pruned... however, unless you still have a reference to the SharedObject, you won't be able to access/reuse the motion after it was pruned)

MMAccessor is a small class, you may consider passing it around instead of a MotionManager::MC_ID if appropriate. (Would be appropriate to avoid multiple checkin/outs in a row from different functions, but not as appropriate for storage and reuse of the same MMAccessor.)

Definition at line 68 of file MMAccessor.h.

List of all members.

Public Member Functions

 MMAccessor (MotionManager::MC_ID id, bool ckout=true)
 constructor, checks out by default
 MMAccessor (MC_t &ptr, bool ckout=true)
 constructor, allows objects to provide uniform access to MotionCommands, regardless of whether they are currently in the MotionManager
 MMAccessor (const MMAccessor &a)
 copy constructor - will reference the same mc_id - checkin/checkouts are independent between this and a; however, if a is checked out, this will check itself out as well
 ~MMAccessor ()
 destructor, checks in if needed
MMAccessor< MC_t > operator= (const MMAccessor< MC_t > &a)
 allows assignment of MMAccessor's, similar to the copy constructor - the two MMAccessor's will control the same MotionCommand
MC_t * checkout (bool throwOnNULL=true)
 So you can check out if not done by default (or you checked in already).
MC_t * mc () const
 Returns the motion command's address so you can call functions.
void checkin ()
 Checks in the motion.
template<class Ret_t >
Ret_t checkin (Ret_t ret)
 Checks in the motion, passing through the value it is passed.
MC_t * operator-> ()
 smart pointer to the underlying MotionCommand
const MC_t * operator-> () const
 smart pointer to the underlying MotionCommand
MC_t & operator* ()
 smart pointer to the underlying MotionCommand
const MC_t & operator* () const
 smart pointer to the underlying MotionCommand
MC_t & operator[] (int i)
 smart pointer to the underlying MotionCommand
const MC_t & operator[] (int i) const
 smart pointer to the underlying MotionCommand

Protected Attributes

MotionManager::MC_ID mc_id
 the MC_ID that this Accessor was constructed with
unsigned int checkOutCnt
 counter so we know how many times checkout was called
MC_t * mcptr
 a pointer to the motion command, should always be valid even when not checked out so you can access member fields (which is reasonably safe)

Constructor & Destructor Documentation

template<class MC_t>
MMAccessor< MC_t >::MMAccessor ( MotionManager::MC_ID  id,
bool  ckout = true 
)

constructor, checks out by default

Parameters:
id the motion command to check out
ckout if true (default) will checkout upon creation. otherwise it just gets current address (so you can peek at member fields, which should be safe)

Definition at line 74 of file MMAccessor.h.

template<class MC_t>
MMAccessor< MC_t >::MMAccessor ( MC_t &  ptr,
bool  ckout = true 
)

constructor, allows objects to provide uniform access to MotionCommands, regardless of whether they are currently in the MotionManager

if ckout is true (default parameter), will attempt to check out the motion if the motion reports it has a valid ID

Definition at line 83 of file MMAccessor.h.

template<class MC_t>
MMAccessor< MC_t >::MMAccessor ( const MMAccessor< MC_t > &  a  ) 

copy constructor - will reference the same mc_id - checkin/checkouts are independent between this and a; however, if a is checked out, this will check itself out as well

If the original was checked out, this will checkout as well (so checkOutCnt will be 1)

Definition at line 90 of file MMAccessor.h.

template<class MC_t>
MMAccessor< MC_t >::~MMAccessor (  ) 

destructor, checks in if needed

Definition at line 96 of file MMAccessor.h.


Member Function Documentation

template<class MC_t>
template<class Ret_t >
Ret_t MMAccessor< MC_t >::checkin ( Ret_t  ret  ) 

Checks in the motion, passing through the value it is passed.

Returns:
the same value it's passed

Useful in situations like this:

  MMAccessor<myMC> mine(myMC_id);
  if(mine.mc()->foo())
    //do something with motman here

But we want to check in mine ASAP - if we don't reference it anywhere in the if statement, we're leaving the MC locked longer than we need to. How about instead doing this:

  bool cond;
  {MMAccessor<myMC> mine(myMC_id); cond=mine.mc()->foo();}
  if(cond)
    //do something with motman here

But that uses an extra variable... ewwww... so use this function as a pass through to checkin the MC:

  MMAccessor<myMC> mine(myMC_id);
  if(mine.checkin(mine.mc()->foo()))
    //do something with motman here

Definition at line 162 of file MMAccessor.h.

template<class MC_t>
void MMAccessor< MC_t >::checkin (  ) 

Checks in the motion.

Don't forget, you can also just limit the scope using extra { }'s

Definition at line 127 of file MMAccessor.h.

Referenced by MMAccessor< MC_t >::checkin(), and MMAccessor< MC_t >::~MMAccessor().

template<class MC_t>
MC_t* MMAccessor< MC_t >::checkout ( bool  throwOnNULL = true  ) 

So you can check out if not done by default (or you checked in already).

Parameters:
throwOnNULL if true, indicates an exception should be thrown if the checked out motion is NULL (indicates mc_id does not reference an active MC)

Definition at line 114 of file MMAccessor.h.

Referenced by MMAccessor< MC_t >::MMAccessor(), and MMAccessor< MC_t >::operator=().

template<class MC_t>
MC_t* MMAccessor< MC_t >::mc (  )  const
template<class MC_t>
const MC_t& MMAccessor< MC_t >::operator* (  )  const

smart pointer to the underlying MotionCommand

Definition at line 170 of file MMAccessor.h.

template<class MC_t>
MC_t& MMAccessor< MC_t >::operator* (  ) 

smart pointer to the underlying MotionCommand

Definition at line 169 of file MMAccessor.h.

template<class MC_t>
const MC_t* MMAccessor< MC_t >::operator-> (  )  const

smart pointer to the underlying MotionCommand

Definition at line 168 of file MMAccessor.h.

template<class MC_t>
MC_t* MMAccessor< MC_t >::operator-> (  ) 

smart pointer to the underlying MotionCommand

Definition at line 167 of file MMAccessor.h.

template<class MC_t>
MMAccessor<MC_t> MMAccessor< MC_t >::operator= ( const MMAccessor< MC_t > &  a  ) 

allows assignment of MMAccessor's, similar to the copy constructor - the two MMAccessor's will control the same MotionCommand

If the original was checked out, this will checkout as well (so checkOutCnt will be 1)

Definition at line 103 of file MMAccessor.h.

template<class MC_t>
const MC_t& MMAccessor< MC_t >::operator[] ( int  i  )  const

smart pointer to the underlying MotionCommand

Definition at line 172 of file MMAccessor.h.

template<class MC_t>
MC_t& MMAccessor< MC_t >::operator[] ( int  i  ) 

smart pointer to the underlying MotionCommand

Definition at line 171 of file MMAccessor.h.


Member Data Documentation

template<class MC_t>
unsigned int MMAccessor< MC_t >::checkOutCnt [protected]
template<class MC_t>
MotionManager::MC_ID MMAccessor< MC_t >::mc_id [protected]

the MC_ID that this Accessor was constructed with

Definition at line 175 of file MMAccessor.h.

Referenced by MMAccessor< MC_t >::checkin(), MMAccessor< MC_t >::checkout(), MMAccessor< MC_t >::MMAccessor(), and MMAccessor< MC_t >::operator=().

template<class MC_t>
MC_t* MMAccessor< MC_t >::mcptr [protected]

a pointer to the motion command, should always be valid even when not checked out so you can access member fields (which is reasonably safe)

Definition at line 177 of file MMAccessor.h.

Referenced by MMAccessor< MC_t >::checkin(), MMAccessor< MC_t >::checkout(), MMAccessor< MC_t >::mc(), MMAccessor< MC_t >::MMAccessor(), and MMAccessor< MC_t >::operator=().


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

Tekkotsu v5.1CVS
Generated Tue Apr 22 03:51:29 2014 by Doxygen 1.6.3