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   //! Returns the name of the instance (#instanceName)
00022   virtual std::string getName() const { return instanceName; }
00023   
00024   virtual MotionHook* getMotionSink() { return NULL; }
00025   virtual void getSensorSources(std::map<std::string,DataSource*>& sources) { sources.clear(); }
00026   virtual void getImageSources(std::map<std::string,DataSource*>& sources) { sources.clear(); }
00027   
00028   typedef InstanceTracker<DeviceDriver,std::string,Factory1Arg<DeviceDriver,std::string> > registry_t;
00029   static registry_t& getRegistry() { static registry_t registry; return registry; }
00030   
00031   //! allows LoadDataThreads to be notified when a data source is added or removed
00032   class SourceListener {
00033   public:
00034     virtual ~SourceListener() {}; //!< destructor
00035     virtual void dataSourcesUpdated()=0; //!< indicates a data source has been added or removed
00036   };
00037   
00038   //! add a listener to #sourceListeners
00039   virtual void addSourceListener(SourceListener* l) { if(l!=NULL) sourceListeners.insert(l); }
00040   //! remove a listener from #sourceListeners
00041   virtual void removeSourceListener(SourceListener* l) { sourceListeners.erase(l); }
00042   
00043 protected:
00044   //! 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
00045   DeviceDriver(const std::string& /*classname*/, const std::string& instancename)
00046   : plist::Dictionary(), instanceName(instancename), sourceListeners()
00047   {
00048     setLoadSavePolicy(FIXED,SYNC);
00049   }
00050 
00051   //! To be called be "deepest" subclass constructor at the end of construction
00052   /*! Don't want to register until completed construction!  plist::Collection listeners would be
00053    *  triggered and might start performing operations on instance while partially constructed */
00054   virtual void registerInstance() {
00055     if(DeviceDriver * inst=getRegistry().getInstance(instanceName)) {
00056       if(inst==this)
00057         return; // duplicate registration, skip it
00058       std::cerr << "Warning: registration of DeviceDriver " << getClassName() << " named " << instanceName << " @ " << this
00059       << " blocked by previous " << inst->getClassName() << " instance of same name @ " << inst << std::endl;
00060     }
00061     if(!getRegistry().registerInstance(getClassName(),instanceName,this))
00062       std::cerr << "Error: failed to register " << getClassName() << " named " << instanceName << " @ " << this;
00063     //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 ** ");
00064   }
00065   
00066   //! calls SourceListener::dataSourcesUpdated() for entries registered in #sourceListeners
00067   virtual void fireDataSourcesUpdated() {
00068     std::set<SourceListener*> notify=sourceListeners;
00069     for(std::set<SourceListener*>::const_iterator it=notify.begin(); it!=notify.end(); ++it) {
00070       if(sourceListeners.find(*it)!=sourceListeners.end()) // check that it hasn't been removed during course of processing...
00071         (*it)->dataSourcesUpdated();
00072     }
00073   }
00074   
00075   const std::string instanceName; //!< holds the name of this instance of CommPort (mainly for error message reporting by the class itself)
00076   std::set<SourceListener*> sourceListeners; //!< list (of LoadDataThreads) to be notified when a data source is added or removed
00077 };
00078 
00079 /*! @file
00080  * @brief 
00081  * @author Ethan Tira-Thompson (ejt) (Creator)
00082  */
00083 
00084 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:38 2016 by Doxygen 1.6.3