Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

DeviceDriver.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_DeviceDriver_h_
00003 #define INCLUDED_DeviceDriver_h_
00004 
00005 #include "Shared/InstanceTracker.h"
00006 #include "Shared/plistCollections.h"
00007 #include <set>
00008 class MotionHook;
00009 class DataSource;
00010 
00011 //! description of DeviceDriver
00012 class DeviceDriver : public virtual plist::Dictionary {
00013 public:
00014   //! destructor, removes from registry in case we're deleting it from some other source than registry's own destroy()
00015   virtual ~DeviceDriver() { getRegistry().destroy(instanceName); }
00016   
00017   //! Returns the name of the class (aka its type)
00018   /*! Suggested implementation is to declare a static string member, set it to the result of
00019    *  calling the registry's registerType, and then return that member here */
00020   virtual std::string getClassName() const=0;
00021   
00022   virtual MotionHook* getMotionSink() { return NULL; }
00023   virtual void getSensorSources(std::map<std::string,DataSource*>& sources) { sources.clear(); }
00024   virtual void getImageSources(std::map<std::string,DataSource*>& sources) { sources.clear(); }
00025   
00026   typedef InstanceTracker<DeviceDriver,std::string,Factory1Arg<DeviceDriver,std::string> > registry_t;
00027   static registry_t& getRegistry() { static registry_t registry; return registry; }
00028   
00029   //! allows LoadDataThreads to be notified when a data source is added or removed
00030   class SourceListener {
00031   public:
00032     virtual ~SourceListener() {}; //!< destructor
00033     virtual void dataSourcesUpdated()=0; //!< indicates a data source has been added or removed
00034   };
00035   
00036   //! add a listener to #sourceListeners
00037   virtual void addSourceListener(SourceListener* l) { if(l!=NULL) sourceListeners.insert(l); }
00038   //! remove a listener from #sourceListeners
00039   virtual void removeSourceListener(SourceListener* l) { sourceListeners.erase(l); }
00040   
00041 protected:
00042   //! constructor, pass the name of the class's type so we can use it in error messages, and a name for the instance so we can register it for MotionHook's to lookup
00043   DeviceDriver(const std::string& /*classname*/, const std::string& instancename)
00044   : plist::Dictionary(), instanceName(instancename), sourceListeners()
00045   {
00046     setLoadSavePolicy(FIXED,SYNC);
00047   }
00048 
00049   //! To be called be "deepest" subclass constructor at the end of construction
00050   /*! Don't want to register until completed construction!  plist::Collection listeners would be
00051    *  triggered and might start performing operations on instance while partially constructed */
00052   virtual void registerInstance() {
00053     if(DeviceDriver * inst=getRegistry().getInstance(instanceName)) {
00054       if(inst==this)
00055         return; // duplicate registration, skip it
00056       std::cerr << "Warning: registration of DeviceDriver " << getClassName() << " named " << instanceName << " @ " << this
00057       << " blocked by previous " << inst->getClassName() << " instance of same name @ " << inst << std::endl;
00058     }
00059     if(!getRegistry().registerInstance(getClassName(),instanceName,this))
00060       std::cerr << "Error: failed to register " << getClassName() << " named " << instanceName << " @ " << this;
00061     //addEntry(".type",new plist::Primitive<std::string>(className),"Stores the typename of the device driver so it can be re-instantiated on load.\n** Do not edit ** ");
00062   }
00063   
00064   //! calls SourceListener::dataSourcesUpdated() for entries registered in #sourceListeners
00065   virtual void fireDataSourcesUpdated() {
00066     std::set<SourceListener*> notify=sourceListeners;
00067     for(std::set<SourceListener*>::const_iterator it=notify.begin(); it!=notify.end(); ++it) {
00068       if(sourceListeners.find(*it)!=sourceListeners.end()) // check that it hasn't been removed during course of processing...
00069         (*it)->dataSourcesUpdated();
00070     }
00071   }
00072   
00073   const std::string instanceName; //!< holds the name of this instance of CommPort (mainly for error message reporting by the class itself)
00074   std::set<SourceListener*> sourceListeners; //!< list (of LoadDataThreads) to be notified when a data source is added or removed
00075 };
00076 
00077 /*! @file
00078  * @brief 
00079  * @author Ethan Tira-Thompson (ejt) (Creator)
00080  *
00081  * $Author: ejt $
00082  * $Name: tekkotsu-4_0 $
00083  * $Revision: 1.7 $
00084  * $State: Exp $
00085  * $Date: 2007/08/23 01:12:53 $
00086  */
00087 
00088 #endif

Tekkotsu Hardware Abstraction Layer 4.0
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4