|
Urbi SDK Remote for C++
2.7.5
|
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