Urbi SDK Remote for C++  2.7.5
uobject.hh
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009-2012, Gostai S.A.S.
00003  *
00004  * This software is provided "as is" without warranty of any kind,
00005  * either expressed or implied, including but not limited to the
00006  * implied warranties of fitness for a particular purpose.
00007  *
00008  * See the LICENSE file for more information.
00009  */
00010 
00012 
00013 #ifndef URBI_UOBJECT_HH
00014 # define URBI_UOBJECT_HH
00015 
00016 # include <libport/warning-push.hh>
00017 
00018 # include <string>
00019 
00020 # include <libport/cmath>
00021 # include <libport/compiler.hh>
00022 # include <libport/fwd.hh>
00023 # include <libport/preproc.hh>
00024 # include <libport/thread-pool.hh>
00025 # include <libport/ufloat.h>
00026 # include <libport/utime.hh>
00027 
00028 # include <urbi/export.hh>
00029 # include <urbi/fwd.hh>
00030 # include <urbi/kernel-version.hh>
00031 # include <urbi/input-port.hh>
00032 # include <urbi/ucallbacks.hh>
00033 # include <urbi/uevent.hh>
00034 # include <urbi/utimer-callback.hh>
00035 # include <urbi/uvar.hh>
00036 # include <urbi/uobject-hub.hh>
00037 # include <urbi/ucontext.hh>
00038 
00039 # ifndef URBI_SDK_DEPRECATED
00040 #  ifdef BUILDING_URBI_SDK
00041 #   define URBI_SDK_DEPRECATED
00042 #  else
00043 #   define URBI_SDK_DEPRECATED ATTRIBUTE_DEPRECATED
00044 #  endif
00045 # endif
00046 
00047 // Tell our users that it is fine to use void returning functions.
00048 # define USE_VOID 1
00049 
00050 # define URBI_UOBJECT_VERSION 2
00051 
00057 # define UBindVarRename(Obj, X, Uname)          \
00058   (X).init(__name, Uname, ctx_)
00059 
00060 # define UBindVar(Obj, X)                       \
00061   UBindVarRename(Obj, X, #X)
00062 
00064 # define UBindVars(Obj, ...)                            \
00065   LIBPORT_VAARGS_APPLY(URBI_BINDVARS, Obj, __VA_ARGS__)
00066 
00067 
00073 # define UBindEventRename(Obj, X, Uname)        \
00074   (X).init(__name, Uname, ctx_)
00075 
00076 # define UBindEvent(Obj,X)                      \
00077   UBindEventRename(Obj, X, #X)
00078 
00079 # define UBindEvents(Obj, ...)                                  \
00080   LIBPORT_VAARGS_APPLY(URBI_BINDEVENTS, Obj, __VA_ARGS__)
00081 
00089 # define UOwned(X)                              \
00090   (X).setOwned()
00091 
00093 # define USensor(X)                             \
00094   UOwned(X)
00095 
00097 # define CREATE_CLASS_LOCK                      \
00098   virtual                                       \
00099   libport::ThreadPool::rTaskLock                \
00100   getClassTaskLock()                            \
00101   {                                             \
00102     static libport::ThreadPool::rTaskLock       \
00103       tl(new libport::ThreadPool::TaskLock);    \
00104     return tl;                                  \
00105   }
00106 
00108 # define URBI_CREATE_CALLBACK(Kind, ...)                        \
00109   ::urbi::createUCallback(*this, 0, #Kind, this, __VA_ARGS__)
00110 
00116 # define UBindFunctionRename(Obj, X, Uname)                     \
00117   URBI_CREATE_CALLBACK(function, (&Obj::X), __name + "." Uname)
00118 
00119 # define UBindFunction(Obj, X)                  \
00120   UBindFunctionRename(Obj, X, #X)
00121 
00122 # define UBindFunctions(Obj, ...)                               \
00123   LIBPORT_VAARGS_APPLY(URBI_BINDFUNCTIONS, Obj, __VA_ARGS__)
00124 
00135 # define UBindThreadedFunctionRename(Obj, X, Uname, LockMode)           \
00136   UBindFunctionRename(Obj, X, Uname)->setAsync(getTaskLock(LockMode, Uname))
00137 
00138 # define UBindThreadedFunction(Obj, X, LockMode)        \
00139   UBindThreadedFunctionRename(Obj, X, #X, LockMode)
00140 
00141 
00146 # define UAt(Obj, X)                                            \
00147   URBI_CREATE_CALLBACK(event, (&Obj::X), __name + "." #X)
00148 
00150 # define UThreadedAt(Obj, X, LockMode)                  \
00151   UAt(Obj, X)->setAsync(getTaskLock(LockMode, #X))
00152 
00153 
00160 # define UAtEnd(Obj, X, Fun)                                            \
00161   URBI_CREATE_CALLBACK(eventend, (&Obj::X), (&Obj::Fun), __name + "." #X)
00162 
00163 # define UThreadedAtEnd(Obj, X, Fun, LockMode)                  \
00164   UAtEnd(Obj, X, Fun)->setAsync(getTaskLock(LockMode, #X))
00165 
00167 # define URegister(Hub)                                         \
00168   do {                                                          \
00169     objecthub = ::urbi::baseURBIStarterHub::find(#Hub);         \
00170     if (objecthub)                                              \
00171       objecthub->addMember(this);                               \
00172     else                                                        \
00173     {                                                           \
00174       GD_CATEGORY(Urbi.UObject);                                \
00175       GD_FERROR("Error: hub name '%s' is unknown",  #Hub);      \
00176     }                                                           \
00177   } while (0)
00178 
00179 
00180 //macro to send urbi commands
00181 # ifndef URBI
00182 
00183 
00184 #   define URBI(A)                              \
00185   uobject_unarmorAndSend(# A)
00186 # endif
00187 
00188 
00191 # define URBI_SEND_C(C, Args)                   \
00192   do {                                          \
00193     libport::BlockLock bl((C).sendBufferLock);  \
00194     (C) << Args;                                \
00195   } while (false)
00196 
00199 # define URBI_SEND_C_FLUSH(C, Args)             \
00200   do {                                          \
00201     libport::BlockLock bl((C).sendBufferLock);  \
00202     (C) << Args << std::endl;                   \
00203   } while (false)
00204 
00207 # define URBI_SEND(Args)                        \
00208   URBI_SEND_C(URBI(()), Args)
00209 
00211 # define URBI_SEND_COMMAND_C(C, Args)           \
00212   URBI_SEND_C_FLUSH(C, Args << ';')
00213 
00214 # define URBI_SEND_COMMAND(Args)                \
00215   URBI_SEND_COMMAND_C(URBI(()), Args)
00216 
00221 # define URBI_SEND_PIPED_COMMAND_C(C, Args)     \
00222   URBI_SEND_C(C, Args << "|\n")
00223 
00224 # define URBI_SEND_PIPED_COMMAND(Args)          \
00225   URBI_SEND_PIPED_COMMAND_C(URBI(()), Args)
00226 
00227 # define URBI_SEND_COMMA_COMMAND_C(C, Args)     \
00228   URBI_SEND_C_FLUSH(C, Args << ',')
00229 
00230 # define URBI_SEND_COMMA_COMMAND(Args)          \
00231   URBI_SEND_COMMA_COMMAND_C(URBI(()), Args)
00232 
00233 namespace urbi
00234 {
00235 
00240   enum LockMode
00241   {
00242     LOCK_NONE,      
00243 
00246     LOCK_FUNCTION,
00247     LOCK_INSTANCE,  
00248     LOCK_CLASS,     
00249     LOCK_MODULE     
00250   };
00251 
00255   class URBI_SDK_API LockSpec
00256   {
00257   public:
00258     LockSpec(LockMode l, unsigned int maxQueueSize = 0)
00259       : lockMode(l)
00260       , maxQueueSize(maxQueueSize)
00261     {}
00262     LockMode lockMode;
00263     unsigned int maxQueueSize;
00264   };
00265 
00269   static const LockSpec LOCK_FUNCTION_DROP = LockSpec(LOCK_FUNCTION, 1);
00270 
00275   static const LockSpec LOCK_FUNCTION_KEEP_ONE = LockSpec(LOCK_FUNCTION, 2);
00276 
00277   UObjectHub* getUObjectHub(const std::string& n);
00278   UObject* getUObject(const std::string& n);
00279   void uobject_unarmorAndSend(const char* str);
00280   void send(const char* str);
00281   void send(const std::string&s);
00282   void send(const void* buf, size_t size);
00283   UObjectMode getRunningMode();
00284   bool isPluginMode();
00285   bool isRemoteMode();
00286 
00288   URBI_SDK_API void setThreadLimit(size_t nThreads);
00290   URBI_SDK_API std::string getFilteredHostname();
00291 
00292   typedef int UReturn;
00293 
00299   class URBI_SDK_API UObject: public UContext
00300   {
00301   public:
00303     UObject(impl::UContextImpl* impl = 0);
00305     UObject(const std::string&, impl::UContextImpl* impl = 0);
00307     UObject(int, impl::UContextImpl* impl = 0);
00308     virtual ~UObject();
00309 
00310 
00311     // This call registers both an UObject (say of type
00312     // UObjectDerived), and a callback working on it (named here
00313     // fun).
00314 
00315     // These macros provide the following callbacks :
00316     // Notify
00317     // Access    | const std::string& | F        | const
00318     // Change    | urbi::UVar&        | F        | non-const
00319 
00320 # ifdef DOXYGEN
00321     // Doxygen does not handle macros very well so feed it simplified code.
00322 
00336     void UNotifyChange(UVar& v, void (UObject::*fun)(UVar&));
00337 
00342     template<typename T>
00343     void UNotifyChange(UVar& v, void (UObject::*fun)(T));
00344 
00351     void
00352     UNotifyThreadedChange(UVar& v, void (UObject::*fun)(UVar&), LockMode m);
00353 
00360     void
00361     UNotifyThreadedChange(UVar& v, void (UObject::*fun)(UVar&), LockSpec s);
00362 
00370     void
00371     UNotifyAccess(UVar& v, void (UObject::*fun)(UVar&));
00372     void
00373     UNotifyThreadedAccess(UVar& v, void (UObject::*fun)(UVar&), LockMode m);
00374     void
00375     UNotifyThreadedAccess(UVar& v, void (UObject::*fun)(UVar&), LockSpec s);
00378 
00379     template <class T>
00380     TimerHandle
00381     USetTimer(ufloat t, void (T::*fun)());
00382 
00383 # else // !DOXYGEN
00384 
00386 #  define MakeNotify(Type, Notified,                    \
00387                      TypeString, Owned, Name,           \
00388                      StoreArg)                          \
00389     template <typename F>                               \
00390     void UNotify##Type(Notified, F fun)                 \
00391     {                                                   \
00392         createUCallback(*this, StoreArg, TypeString,    \
00393                         this, fun, Name);               \
00394     }                                                   \
00395     template <typename F>                               \
00396     void UNotifyThreaded##Type(Notified, F fun,         \
00397                                LockMode lockMode)       \
00398     {                                                   \
00399         createUCallback(*this, StoreArg, TypeString,    \
00400                         this, fun, Name)                \
00401           ->setAsync(getTaskLock(lockMode, Name));      \
00402     }                                                   \
00403     template <typename F>                               \
00404     void UNotifyThreaded##Type(Notified, F fun,         \
00405                                LockSpec lockMode)       \
00406     {                                                   \
00407         createUCallback(*this, StoreArg, TypeString,    \
00408                         this, fun, Name)                \
00409           ->setAsync(getTaskLock(lockMode, Name));      \
00410     }
00411 
00412 
00413 
00415 #  define MakeMetaNotify(Type, TypeString)                              \
00416     MakeNotify(Type, UVar& v, TypeString,                               \
00417                v.owned, v.get_name (),                                  \
00418                v.get_temp()?new UVar(v.get_name(), ctx_):&v);           \
00419     MakeNotify(Type, InputPort& v, TypeString,                          \
00420                v.owned, v.get_name (),                                  \
00421                &v);                                                     \
00422     MakeNotify(Type, const std::string& name, TypeString,               \
00423                false, name, new UVar(name, ctx_));
00424 
00426     MakeMetaNotify(Access, "varaccess");
00427 
00429     MakeMetaNotify(Change, "var");
00430 
00431 #  undef MakeNotify
00432 #  undef MakeMEtaNotify
00433 
00434 #  ifndef SWIG
00435 
00436 #   define MKUSetTimer(Const, Useless)                                  \
00437     template <class T, class R>                                         \
00438     TimerHandle USetTimer(ufloat t, R (T::*fun) () Const)               \
00439     {                                                                   \
00440       return (new UTimerCallbackobj<T>                                  \
00441               (__name, t,                                               \
00442                dynamic_cast<T*>(this),                                  \
00443                boost::bind(fun, dynamic_cast<T*>(this)),                \
00444                ctx_))                                                   \
00445         ->handle_get();                                                 \
00446     }
00447 
00448     MKUSetTimer (, );
00449     MKUSetTimer (const, );
00450 
00451 #   undef MKUSetTimer
00452 #  endif // !SWIG
00453 # endif // DOXYGEN
00454 
00456     bool removeTimer(TimerHandle h);
00457 
00459     void USync(UVar &v);
00460 
00462     std::string __name;
00464     std::string classname;
00466     bool derived;
00467 
00468     UObjectList members;
00469 
00471     UObjectHub* objecthub;
00472 
00475     void USetUpdate(ufloat period);
00476     virtual int update();
00477 
00478 
00484     URBI_SDK_DEPRECATED
00485     void UAutoGroup();
00487     URBI_SDK_DEPRECATED
00488     virtual void addAutoGroup();
00489 
00491     URBI_SDK_DEPRECATED
00492     virtual void UJoinGroup(const std::string& gpname);
00493 
00495     URBI_SDK_DEPRECATED
00496     bool autogroup;
00498 
00500     int voidfun();
00501 
00503     bool remote;
00504 
00506     void clean();
00507 
00509     libport::ThreadPool::rTaskLock getTaskLock(LockMode m,
00510                                                const std::string& what);
00512     libport::ThreadPool::rTaskLock getTaskLock(LockSpec s,
00513                                                const std::string& what);
00516     UVar load;
00517 
00518     baseURBIStarter* cloner;
00519 
00520     impl::UObjectImpl* impl_get();
00521 
00522     // Override me to have your own LOCK_CLASS task lock.
00523     virtual libport::ThreadPool::rTaskLock getClassTaskLock();
00524   private:
00527     UObjectData* objectData;
00528 
00529     impl::UObjectImpl* impl_;
00530     boost::unordered_map<std::string, libport::ThreadPool::rTaskLock>
00531     taskLocks_;
00533     libport::ThreadPool::rTaskLock taskLock_;
00534   };
00535 
00536 #ifndef NO_UOBJECT_CASTER
00537   // Provide cast support to UObject*
00538   template<> struct uvalue_caster<UObject*>
00539   {
00540     UObject* operator()(urbi::UValue& v);
00541   };
00542   UValue& operator,(UValue&a, const UObject* b);
00543 #endif
00544 } // end namespace urbi
00545 
00546 // This file needs the definition of UObject, so included last.
00547 // To be cleaned later.
00548 # include <urbi/ustarter.hh>
00549 
00550 # include <urbi/uobject.hxx>
00551 
00552 # include <libport/warning-pop.hh>
00553 
00554 #endif // ! URBI_UOBJECT_HH