Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1 Paragraph1
Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2 Paragraph2
Paragraph Paragraph Paragraph Paragraph Paragraph
list2
Paragraph Paragraph Paragraph Paragraph Paragraph
Paragraph Paragraph Paragraph Paragraph Paragraph
1 class TAgent { public: TAgent () : modules_ ("TAgent","global"), conf_ (modules_.ParamBoxConfig().SetMemberMap()), path_list_ (NULL) { modules_.SetAgent(*this); } virtual ~TAgent() {} ... };
1 //------------------------------------------------------------------------------------------- 2 /*! \file base.h 3 \brief libskyai - base unit (header) 4 \author Akihiko Yamaguchi, akihiko-y@is.naist.jp / ay@akiyam.sakura.ne.jp 5 \date Aug.24, 2009- 6 7 Copyright (C) 2009, 2010 Akihiko Yamaguchi 8 9 This file is part of SkyAI. 10 11 This program is free software: you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation, either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 //------------------------------------------------------------------------------------------- 25 #ifndef skyai_base_h 26 #define skyai_base_h 27 //------------------------------------------------------------------------------------------- 28 #include <lora/common.h> 29 #include <lora/string.h> 30 #include <lora/variable_space.h> 31 #include <climits> 32 #include <string> 33 #include <list> 34 #include <map> 35 #include <set> 36 #include <boost/function.hpp> 37 #include <skyai/module_manager.h> 38 //------------------------------------------------------------------------------------------- 39 // forward declarations: 40 namespace boost {namespace filesystem { 41 struct path_traits; 42 template<class String, class Traits> class basic_path; 43 typedef basic_path< std::string, path_traits > path; 44 }} 45 namespace loco_rabbits {namespace var_space { 46 struct TLiteral; 47 }} 48 //------------------------------------------------------------------------------------------- 49 namespace loco_rabbits 50 { 51 //------------------------------------------------------------------------------------------- 52 53 //------------------------------------------------------------------------------------------- 54 static const int SKYAI_CONNECTION_SIZE_MAX (INT_MAX); 55 //------------------------------------------------------------------------------------------- 56 static const char * const SKYAI_DISABLED_FWD_PORT_NAME ("-"); //!< used to be a disabled forwarding signal port name 57 //------------------------------------------------------------------------------------------- 58 static const char * const SKYAI_MODULE_NAME_DELIMITER ("-"); 59 //------------------------------------------------------------------------------------------- 60 static const char * const SKYAI_MODULE_PORT_DELIMITER ("."); 61 //------------------------------------------------------------------------------------------- 62 static const char * const SKYAI_EXT_STORAGE_DIR ("ext_sto"); 63 //------------------------------------------------------------------------------------------- 64 /*!\note we define SKYAI_DEFAULT_AGENT_SCRIPT_EXT as a macro rather than a const variable 65 so that "."SKYAI_DEFAULT_AGENT_SCRIPT_EXT can indicate ".agent" */ 66 #define SKYAI_DEFAULT_AGENT_SCRIPT_EXT "agent" 67 //------------------------------------------------------------------------------------------- 68 69 class TPortInterface; 70 class TModuleInterface; 71 class TCompositeModule; 72 class TAgent; 73 74 enum TPortKind {pkUnknown=0,pkOut,pkIn,pkSignal,pkSlot}; 75 76 ENUM_STR_MAP_BEGIN(TPortKind) 77 ENUM_STR_MAP_ADD(pkUnknown ) 78 ENUM_STR_MAP_ADD(pkOut ) 79 ENUM_STR_MAP_ADD(pkIn ) 80 ENUM_STR_MAP_ADD(pkSignal ) 81 ENUM_STR_MAP_ADD(pkSlot ) 82 ENUM_STR_MAP_END (TPortKind) 83 84 struct TPortInfo 85 { 86 TPortKind Kind; 87 std::string Name; 88 TPortInterface *Ptr; 89 TModuleInterface *OuterModule; 90 TPortInfo() : Kind(pkUnknown), Name(""), Ptr(NULL), OuterModule(NULL) {} 91 }; 92 struct TConstPortInfo 93 { 94 TPortKind Kind; 95 std::string Name; 96 const TPortInterface *Ptr; 97 const TModuleInterface *OuterModule; 98 TConstPortInfo() : Kind(pkUnknown), Name(""), Ptr(NULL), OuterModule(NULL) {} 99 }; 100 //------------------------------------------------------------------------------------------- 101 102 //=========================================================================================== 103 /*!\brief define the interface of ports */ 104 class TPortInterface 105 //=========================================================================================== 106 { 107 public: 108 109 TPortInterface (const TModuleInterface &v_outer_base, const std::string v_name, int v_max_connection_size) 110 : outer_base_ (v_outer_base), 111 name_ (v_name), 112 max_connection_size_ (v_max_connection_size), 113 active_counter_ (0), 114 never_called_ (true) 115 {} 116 117 virtual ~TPortInterface() {} 118 119 /*!\brief Connect v_port to this port (return true if successful) */ 120 virtual bool Connect (TPortInterface &v_port) = 0; 121 122 /*!\brief Disconnect the connection with the port specified by port_ptr (disconnected:true) */ 123 virtual bool Disconnect (const TPortInterface *port_ptr) = 0; 124 125 virtual int ConnectionSize() const = 0; 126 127 /*!\brief for each connected port, apply the function f 128 \note if the return of the function f is false, the iteration is finished immidiately, 129 else the iteration is continued. */ 130 virtual void ForEachConnectedPort (boost::function<bool(TPortInterface*)> f) = 0; 131 132 /*!\brief for each connected port, apply the function f 133 \note if the return of the function f is false, the iteration is finished immidiately, 134 else the iteration is continued. */ 135 virtual void ForEachConnectedPort (boost::function<bool(const TPortInterface*)> f) const = 0; 136 137 /*!\brief get the original name of the port 138 \note a port of a module can be exported as a port of the module's parent_cmodule_. 139 in this case, the name of the exported port is arbitrary, i.e. not equal to the OriginalName(). */ 140 const std::string& OriginalName() const {return name_;} 141 142 const int& MaxConnectionSize() const {return max_connection_size_;} 143 144 bool IsActive() const {LASSERT1op1(active_counter_,>=,0); return active_counter_>0;} 145 146 bool NeverCalled() const {return never_called_;} 147 void SetNeverCalled (bool nc) {never_called_= nc;} 148 149 protected: 150 151 const TModuleInterface &outer_base_; 152 153 const std::string name_; 154 int max_connection_size_; 155 156 mutable int active_counter_; //!< if positive, the outer module should not be removed 157 158 struct TActivate 159 { 160 const TPortInterface &Outer; 161 TActivate(const TPortInterface &o) : Outer(o) {++Outer.active_counter_;} 162 ~TActivate() {--Outer.active_counter_;} 163 }; 164 165 mutable bool never_called_; //!< if true, this port has not been executed after generated 166 167 inline void first_call_check() const; 168 169 private: 170 171 TPortInterface(const TPortInterface&); 172 const TPortInterface& operator=(const TPortInterface&); 173 174 }; 175 //------------------------------------------------------------------------------------------- 176 177 class TOutPortInterface : public TPortInterface 178 { 179 public: 180 181 TOutPortInterface (const TModuleInterface &v_outer_base, const std::string v_name, int v_max_connection_size=SKYAI_CONNECTION_SIZE_MAX) : 182 TPortInterface (v_outer_base, v_name, v_max_connection_size) 183 {} 184 185 protected: 186 }; 187 //------------------------------------------------------------------------------------------- 188 189 class TInPortInterface : public TPortInterface 190 { 191 public: 192 193 TInPortInterface (const TModuleInterface &v_outer_base, const std::string v_name, int v_max_connection_size=1) : 194 TPortInterface (v_outer_base, v_name, v_max_connection_size) 195 {} 196 197 protected: 198 }; 199 //------------------------------------------------------------------------------------------- 200 201 class TSignalPortInterface : public TPortInterface 202 { 203 public: 204 205 TSignalPortInterface (const TModuleInterface &v_outer_base, const std::string v_name, int v_max_connection_size=SKYAI_CONNECTION_SIZE_MAX) : 206 TPortInterface (v_outer_base, v_name, v_max_connection_size) 207 {} 208 209 protected: 210 }; 211 //------------------------------------------------------------------------------------------- 212 213 class TSlotPortInterface : public TPortInterface 214 { 215 public: 216 217 TSlotPortInterface (const TModuleInterface &v_outer_base, const std::string v_name, int v_max_connection_size=SKYAI_CONNECTION_SIZE_MAX) 218 : TPortInterface (v_outer_base, v_name, v_max_connection_size) 219 {} 220 221 /*!\brief return the reference to the forwarding-signal-port 222 that is emitted after the slot (exec_) is executed */ 223 virtual TSignalPortInterface& ForwardingSinalPortBase() = 0; 224 225 protected: 226 }; 227 //------------------------------------------------------------------------------------------- 228 229 230 //------------------------------------------------------------------------------------------- 231 /*!\brief This macro generates basic member functions about module name. 232 Use at the public section of a module class. 233 \note This module-name string (ModuleName()) is referred from SKYAI_ADD_MODULE macro, 234 and registered to TModuleManager with this name. 235 TModuleManager generates an instance of the module from a module-name string. 236 Thus, the module-name string should be unique. 237 Basically, use string stringized from the module-class name. 238 239 \note <b>For a template module case</b>, because we cannot directoly register the template to TModuleManager, 240 we (1) explicitly instantiate the template module with some types, (2) typedef them as unique names, 241 and (3) register them into TModuleManager with their unique name given by typedef. 242 In such a case, we have to specialize ModuleName() for template instances. 243 Actually, use SKYAI_INSTANTIATE_TEMPLATE_MODULE_N and SKYAI_SPECIALIZE_TEMPLATE_MODULE_N macros 244 whith automatically do the instantiating and specializing processes. */ 245 #define SKYAI_MODULE_NAMES(x_module_name) \ 246 static std::string ModuleName() {return std::string(#x_module_name);} \ 247 virtual std::string InheritedModuleName() const {return ModuleName();} 248 //------------------------------------------------------------------------------------------- 249 250 //!\TODO Automate to generate the following macros (up to about 10) 251 252 /*!\brief This macro specializes and instantiates a template module (for 1 template argument) 253 \note Use in the namespace loco_rabbits. 254 \note This macro gives the instance an unique name (typedef), specializes ModuleName(), 255 and explicitly instantiates the template module. 256 \note The unique name of a module Module1 instantiated with Type1 is Module1_Type1, 257 and ModuleName() gives "Module1_Type1" */ 258 #define SKYAI_INSTANTIATE_TEMPLATE_MODULE_1(x_module_name,x_type_1) \ 259 typedef x_module_name<x_type_1> x_module_name##_##x_type_1; \ 260 template<> std::string x_module_name<x_type_1>::ModuleName() \ 261 {return std::string(#x_module_name "_" #x_type_1);} \ 262 template class x_module_name<x_type_1>; 263 /*!\brief This macro specializes and instantiates a template module (for 2 template argument) */ 264 #define SKYAI_INSTANTIATE_TEMPLATE_MODULE_2(x_module_name,x_type_1,x_type_2) \ 265 typedef x_module_name<x_type_1,x_type_2> x_module_name##_##x_type_1##_##x_type_2; \ 266 template<> std::string x_module_name<x_type_1,x_type_2>::ModuleName() \ 267 {return std::string(#x_module_name "_" #x_type_1 "_" #x_type_2);} \ 268 template class x_module_name<x_type_1,x_type_2>; 269 /*!\brief This macro specializes and instantiates a template module (for 3 template argument) */ 270 #define SKYAI_INSTANTIATE_TEMPLATE_MODULE_3(x_module_name,x_type_1,x_type_2,x_type_3) \ 271 typedef x_module_name<x_type_1,x_type_2,x_type_3> x_module_name##_##x_type_1##x_type_2##x_type_3; \ 272 template<> std::string x_module_name<x_type_1,x_type_2,x_type_3>::ModuleName() \ 273 {return std::string(#x_module_name "_" #x_type_1 "_" #x_type_2 "_" #x_type_3);} \ 274 template class x_module_name<x_type_1,x_type_2,x_type_3>; 275 276 /*!\brief This macro generates a declaration of specializing a template module (for 1 template argument) 277 \note Use in the namespace loco_rabbits. 278 Use in a header file. 279 \warning Even if you do not use these macros, you can compile the code. 280 However, the compiler fails in specializing a module that is inherited from 281 the template module. */ 282 #define SKYAI_SPECIALIZE_TEMPLATE_MODULE_1(x_module_name,x_type_1) \ 283 template<> std::string x_module_name<x_type_1>::ModuleName(); 284 /*!\brief This macro generates a declaration of specializing a template module (for 2 template argument) */ 285 #define SKYAI_SPECIALIZE_TEMPLATE_MODULE_2(x_module_name,x_type_1,x_type_2) \ 286 template<> std::string x_module_name<x_type_1,x_type_2>::ModuleName(); 287 /*!\brief This macro generates a declaration of specializing a template module (for 3 template argument) */ 288 #define SKYAI_SPECIALIZE_TEMPLATE_MODULE_3(x_module_name,x_type_1,x_type_2,x_type_3) \ 289 template<> std::string x_module_name<x_type_1,x_type_2,x_type_3>::ModuleName(); 290 291 //------------------------------------------------------------------------------------------- 292 293 294 //=========================================================================================== 295 /*!\brief Base class of every module (every skyai module is required to be inherited from this class) */ 296 class TModuleInterface 297 //=========================================================================================== 298 { 299 public: 300 301 template <typename t_port> 302 struct TPortSet 303 { 304 typedef std::map<std::string, t_port> type; 305 }; 306 307 enum TModuleMode {mmNormal=0, mmDebug}; 308 309 static std::string ModuleName() {return std::string("TModuleInterface");} 310 virtual std::string InheritedModuleName() const {return ModuleName();} 311 312 std::string InstanceName() const 313 {return instance_name_;} 314 std::string ModuleUniqueCode() const 315 {return InheritedModuleName() + SKYAI_MODULE_NAME_DELIMITER + instance_name_;} 316 317 std::string GlobalUniqueCode() const; 318 319 static std::string PortUniqueCode(const std::string &module_name, const std::string &port_name) 320 {return module_name+SKYAI_MODULE_PORT_DELIMITER+port_name;} 321 std::string PortUniqueCode(const std::string &port_name) const {return PortUniqueCode(InstanceName(), port_name);} 322 323 std::string PortUniqueCode(const TPortInterface &port) const 324 {TConstPortInfo pi; if(!SearchPortByPtr(&port,pi)) return ""; return PortUniqueCode(pi.Name);} 325 326 static bool DecomposePortUniqueCode(const std::string &unique_code, std::string &module_name, std::string &port_name); 327 328 var_space::TVariable& ParamBoxConfig() {first_access_check(); return param_box_config_;} 329 const var_space::TVariable& ParamBoxConfig() const {first_access_check(); return param_box_config_;} 330 331 var_space::TVariable& ParamBoxMemory() {first_access_check(); return param_box_memory_;} 332 const var_space::TVariable& ParamBoxMemory() const {first_access_check(); return param_box_memory_;} 333 334 /*!\brief a constructor of TModuleInterface class. 335 \note any subclasses of the TModuleInterface that are registered to TModuleManager 336 should have the same constructor form as TModuleInterface */ 337 TModuleInterface (const std::string &v_instance_name) 338 : instance_name_ (v_instance_name), 339 pagent_ (NULL), 340 parent_cmodule_ (NULL), 341 param_box_config_ (var_space::VariableSpace()), 342 param_box_memory_ (var_space::VariableSpace()), 343 module_mode_ (mmNormal), 344 debug_stream_ (NULL), 345 is_zombie_ (false), 346 never_accessed_ (true) 347 {} 348 349 virtual ~TModuleInterface(void); 350 351 const TModuleMode& ModuleMode () const {return module_mode_;} 352 virtual void SetModuleMode (const TModuleMode &mm) {module_mode_= mm;} 353 354 std::ostream& DebugStream () const {return (debug_stream_==NULL) ? std::cerr : *debug_stream_;} 355 virtual void SetDebugStream (std::ostream &os) {debug_stream_= &os;} 356 357 358 TOutPortInterface* OutPortPtr (const std::string &v_name); //!<\brief access an out-port by its name 359 const TOutPortInterface* OutPortPtr (const std::string &v_name) const; //!<\brief access an out-port (const) by its name 360 TInPortInterface* InPortPtr (const std::string &v_name); //!<\brief access an in-port by its name 361 const TInPortInterface* InPortPtr (const std::string &v_name) const; //!<\brief access an in-port (const) by its name 362 TSignalPortInterface* SignalPortPtr (const std::string &v_name); //!<\brief access a signal-port by its name 363 const TSignalPortInterface* SignalPortPtr (const std::string &v_name) const; //!<\brief access a signal-port (const) by its name 364 TSlotPortInterface* SlotPortPtr (const std::string &v_name); //!<\brief access a slot-port by its name 365 const TSlotPortInterface* SlotPortPtr (const std::string &v_name) const; //!<\brief access a slot-port (const) by its name 366 367 TOutPortInterface& OutPort (const std::string &v_name); //!<\brief access an out-port by its name 368 const TOutPortInterface& OutPort (const std::string &v_name) const; //!<\brief access an out-port (const) by its name 369 TInPortInterface& InPort (const std::string &v_name); //!<\brief access an in-port by its name 370 const TInPortInterface& InPort (const std::string &v_name) const; //!<\brief access an in-port (const) by its name 371 TSignalPortInterface& SignalPort (const std::string &v_name); //!<\brief access a signal-port by its name 372 const TSignalPortInterface& SignalPort (const std::string &v_name) const; //!<\brief access a signal-port (const) by its name 373 TSlotPortInterface& SlotPort (const std::string &v_name); //!<\brief access a slot-port by its name 374 const TSlotPortInterface& SlotPort (const std::string &v_name) const; //!<\brief access a slot-port (const) by its name 375 376 TPortInterface* PortPtr (const std::string &v_name); //!<\brief access a port by its name 377 const TPortInterface* PortPtr (const std::string &v_name) const; //!<\brief access a port by its name 378 TPortInterface& Port (const std::string &v_name); //!<\brief access a port by its name 379 const TPortInterface& Port (const std::string &v_name) const; //!<\brief access a port by its name 380 381 bool SearchPortByPtr (const TPortInterface *port_ptr, TConstPortInfo &info) const; 382 bool SearchPortByPtr (TPortInterface *port_ptr, TPortInfo &info); 383 384 385 // accessors to iterators 386 387 TPortSet<TOutPortInterface*>::type::iterator OutPortBegin() {return out_ports_.begin();} 388 TPortSet<TOutPortInterface*>::type::iterator OutPortEnd() {return out_ports_.end();} 389 TPortSet<TOutPortInterface*>::type::const_iterator OutPortBegin() const {return out_ports_.begin();} 390 TPortSet<TOutPortInterface*>::type::const_iterator OutPortEnd() const {return out_ports_.end();} 391 392 TPortSet<TInPortInterface*>::type::iterator InPortBegin() {return in_ports_.begin();} 393 TPortSet<TInPortInterface*>::type::iterator InPortEnd() {return in_ports_.end();} 394 TPortSet<TInPortInterface*>::type::const_iterator InPortBegin() const {return in_ports_.begin();} 395 TPortSet<TInPortInterface*>::type::const_iterator InPortEnd() const {return in_ports_.end();} 396 397 TPortSet<TSignalPortInterface*>::type::iterator SignalPortBegin() {return signal_ports_.begin();} 398 TPortSet<TSignalPortInterface*>::type::iterator SignalPortEnd() {return signal_ports_.end();} 399 TPortSet<TSignalPortInterface*>::type::const_iterator SignalPortBegin() const {return signal_ports_.begin();} 400 TPortSet<TSignalPortInterface*>::type::const_iterator SignalPortEnd() const {return signal_ports_.end();} 401 402 TPortSet<TSlotPortInterface*>::type::iterator SlotPortBegin() {return slot_ports_.begin();} 403 TPortSet<TSlotPortInterface*>::type::iterator SlotPortEnd() {return slot_ports_.end();} 404 TPortSet<TSlotPortInterface*>::type::const_iterator SlotPortBegin() const {return slot_ports_.begin();} 405 TPortSet<TSlotPortInterface*>::type::const_iterator SlotPortEnd() const {return slot_ports_.end();} 406 407 408 //!\brief return true if this module has some active ports 409 bool HasActivePorts() const; 410 411 //!\brief set true: the module should be removed, but impossible because some ports are active 412 void SetZombie (bool z) {is_zombie_=z;} 413 414 //!\brief true: the module should be removed, but impossible because some ports are active 415 bool IsZombie() {return is_zombie_;} 416 417 418 //!\brief return the reference to the host agent 419 TAgent& Agent() {LASSERT(pagent_); return *pagent_;} 420 const TAgent& Agent() const {LASSERT(pagent_); return *pagent_;} 421 void SetAgent (TAgent &agent) {pagent_= &agent;} 422 423 //!\brief return the pointer to the host composite module 424 TCompositeModule& ParentCModule() {LASSERT(parent_cmodule_); return *parent_cmodule_;} 425 const TCompositeModule& ParentCModule() const {LASSERT(parent_cmodule_); return *parent_cmodule_;} 426 TCompositeModule* ParentCModulePtr() {return parent_cmodule_;} 427 const TCompositeModule* ParentCModulePtr() const {return parent_cmodule_;} 428 void SetParentCModule (TCompositeModule *parent) {parent_cmodule_= parent;} 429 430 431 virtual void SetNeverAccessed (bool na); 432 void SetLazyLoadFile (const std::string &file_name); 433 434 bool ExecuteFunction (const std::string &func_name, const std::list<var_space::TLiteral> &argv, bool no_export=false); 435 436 437 struct TShowConf 438 { 439 bool ShowInstanceName ; 440 bool ShowUniqueCode ; 441 bool ShowParamsConfig ; 442 bool ShowParamsMemory ; 443 bool ShowPorts ; 444 bool ShowPortsConnection ; 445 bool ShowPortsMaxConnection ; 446 TShowConf() 447 : 448 ShowInstanceName (true), 449 ShowUniqueCode (false), 450 ShowParamsConfig (true), 451 ShowParamsMemory (false), 452 ShowPorts (true), 453 ShowPortsConnection (true), 454 ShowPortsMaxConnection (true) 455 {} 456 }; 457 static void ParseShowConfOption (const std::string &option, TShowConf &conf); 458 void ShowModule (const TShowConf &conf=TShowConf(), std::ostream &os=std::cout) const; 459 void ShowModule (const std::string &option="", std::ostream &os=std::cout) const; 460 461 protected: 462 463 std::string lazy_include_filename_; //!< if not empty, the file is included in on_first_access 464 465 466 /*!\brief parameter box which has links to the configuration parameters of this module */ 467 var_space::TVariableMap& param_box_config_map () {return param_box_config_.SetMemberMap();} 468 469 /*!\brief parameter box which has links to the learning parameters of this module */ 470 var_space::TVariableMap& param_box_memory_map () {return param_box_memory_.SetMemberMap();} 471 472 473 void add_out_port (TOutPortInterface &v_port, const std::string &v_name); 474 void add_in_port (TInPortInterface &v_port, const std::string &v_name); 475 void add_signal_port (TSignalPortInterface &v_port, const std::string &v_name); 476 void add_slot_port (TSlotPortInterface &v_port, const std::string &v_name); //!<\note this method does not add forwarding-sinal-port 477 478 void add_out_port (TOutPortInterface &v_port); 479 void add_in_port (TInPortInterface &v_port); 480 void add_signal_port (TSignalPortInterface &v_port); 481 void add_slot_port (TSlotPortInterface &v_port); //!<\note this method also adds forwarding-sinal-port 482 483 bool remove_port (const std::string &v_name); //!< remove port v_name. return true if removed 484 485 void clear_ports(); 486 487 inline void first_access_check() const; 488 489 virtual void on_first_access(); 490 491 private: 492 493 /*! forbid to copy (every ports and parameter boxes should not be copied) */ 494 const TModuleInterface& operator= (const TModuleInterface &); 495 496 497 const std::string instance_name_; 498 TAgent *pagent_; //!< pointer to the host agent 499 TCompositeModule *parent_cmodule_; //!< pointer to the host composite module 500 /*!\note We want to let pagent_ and parent_cmodule_ a constant object for safety. 501 But, they should be variable to execute a script's function. 502 Thus, I removed a const from them (@Aug.16,2010) */ 503 504 /*!\brief parameter box which has links to the configuration parameters of this module */ 505 var_space::TVariable param_box_config_; 506 507 /*!\brief parameter box which has links to the learning parameters of this module */ 508 var_space::TVariable param_box_memory_; 509 510 TModuleMode module_mode_; 511 std::ostream *debug_stream_; 512 513 bool is_zombie_; //!< true: the module should be removed, but impossible because some ports are active 514 515 mutable bool never_accessed_; //!< if true, this module have not been accessed after generated or SetLazyLoadFile 516 517 /*! the set of out-ports. */ 518 TPortSet<TOutPortInterface*>::type out_ports_; 519 520 /*! the set of in-ports. */ 521 TPortSet<TInPortInterface*>::type in_ports_; 522 523 /*! the set of signal-ports. */ 524 TPortSet<TSignalPortInterface*>::type signal_ports_; 525 526 /*! the set of slot-ports. */ 527 TPortSet<TSlotPortInterface*>::type slot_ports_; 528 529 530 friend class TPortInterface; // this class is friend to access first_access_check() 531 532 // following functions are friend(s) to directly access param_box_* (not to execute first_access_check) 533 friend inline var_space::TVariable& ll_param_box_config(TModuleInterface &m); 534 friend inline var_space::TVariable& ll_param_box_memory(TModuleInterface &m); 535 536 }; 537 //------------------------------------------------------------------------------------------- 538 539 540 //=========================================================================================== 541 /*!\brief Composite module class */ 542 class TCompositeModule : public TModuleInterface 543 //=========================================================================================== 544 { 545 public: 546 547 struct TModuleCell 548 { 549 std::string Name; //! == Ptr->InstanceName 550 TModuleInterface *Ptr; 551 bool Managed; //! if true, Ptr is freed in Clear() if not NULL 552 TModuleCell(void) : Name(""), Ptr(NULL), Managed(true) {} 553 TModuleCell(const std::string &id) : Name(id), Ptr(NULL), Managed(true) {} 554 TModuleCell(const std::string &id, TModuleInterface *m, bool mngd) : Name(id), Ptr(m), Managed(mngd) {} 555 }; 556 557 typedef boost::function<bool(const TPortInfo *from_port, const TPortInfo *to_port)> TConnectionManipulator; 558 typedef boost::function<bool(const TConstPortInfo *from_port, const TConstPortInfo *to_port)> TConstConnectionManipulator; 559 560 561 //! clear all modules (memories are freed) 562 void Clear(); 563 564 override std::string InheritedModuleName() const {return cmodule_name_;} 565 566 TCompositeModule(const std::string &v_cmodule_name, const std::string &v_instance_name) 567 : TModuleInterface (v_instance_name), 568 cmodule_name_ (v_cmodule_name) 569 {} 570 571 virtual ~TCompositeModule() 572 { 573 Clear(); 574 } 575 576 TModuleInterface* SubModulePtr (const std::string &module_name) {return find_sub_module(module_name,/*error=*/false);} 577 const TModuleInterface* SubModulePtr (const std::string &module_name) const {return find_sub_module(module_name,/*error=*/false);} 578 579 TModuleInterface& SubModule (const std::string &module_name); 580 const TModuleInterface& SubModule (const std::string &module_name) const; 581 582 /*! search a module named module_name. 583 if a sub-module is a composite one and max_depth>0, module_name is searched recursively */ 584 TModuleInterface* SearchSubModule (const std::string &module_name, int max_depth=5); 585 /*! search a module named module_name. 586 if a sub-module is a composite one and max_depth>0, module_name is searched recursively */ 587 const TModuleInterface* SearchSubModule (const std::string &module_name, int max_depth=5) const; 588 589 bool SearchSubPort (TPortInterface *port_ptr, TPortInfo &info); 590 bool SearchSubPort (const TPortInterface *port_ptr, TConstPortInfo &info) const; 591 592 TPortInterface* SearchSubPort (const std::string &unique_code); 593 const TPortInterface* SearchSubPort (const std::string &unique_code) const; 594 595 std::string SearchSubPortUniqueCode (const TPortInterface *port_ptr) const; 596 597 template <typename t_module> 598 t_module& SubModuleAs (const std::string &module_name); 599 600 template <typename t_module> 601 const t_module& SubModuleAs (const std::string &module_name) const; 602 603 //! create a module of the specified type 604 template <typename t_module> 605 t_module& AddSubModule (const std::string &v_instance_name); 606 607 //! create a module whose type is specified by the string v_module_class 608 TModuleInterface& AddSubModule (const std::string &v_module_class, const std::string &v_instance_name); 609 610 /*! add p into the sub-module set. this pointer is not managed by this class, 611 i.e. the memory is not freed in Clear(), and parameter is not saved (only connection is saved) */ 612 void AddUnmanagedSubModule (TModuleInterface *p, const std::string &v_instance_name); 613 614 /*! remove a module of the instance name. all connections are disconnected */ 615 bool RemoveSubModule (const std::string &v_instance_name); 616 617 /*! remove all zombies */ 618 bool ClearZombies (); 619 620 /*! connect the two ports. the port types are automatically determined */ 621 bool SubConnect( 622 TModuleInterface &start_module, const std::string &start_port_name, 623 TModuleInterface &end_module, const std::string &end_port_name); 624 625 /*! connect the two ports. the modules are indicated by names. the port types are automatically determined */ 626 bool SubConnect( 627 const std::string &start_module_name, const std::string &start_port_name, 628 const std::string &end_module_name, const std::string &end_port_name); 629 630 /*! disconnect the two ports. the port types are automatically determined */ 631 bool SubDisconnect( 632 TModuleInterface &start_module, const std::string &start_port_name, 633 TModuleInterface &end_module, const std::string &end_port_name); 634 635 /*! disconnect the two ports. the modules are indicated by names. the port types are automatically determined */ 636 bool SubDisconnect( 637 const std::string &start_module_name, const std::string &start_port_name, 638 const std::string &end_module_name, const std::string &end_port_name); 639 640 641 /*!\brief for each module, apply the function f */ 642 void ForEachSubModule (boost::function<bool(TModuleInterface* module)> f); 643 644 /*!\brief for each module, apply the function f */ 645 void ForEachSubModule (boost::function<bool(const TModuleInterface* module)> f) const; 646 647 /*!\brief for each module, apply the function f */ 648 void ForEachSubModuleCell (boost::function<bool(const TModuleCell &mcell)> f) const; 649 650 /*!\brief for each connected port, apply the function f */ 651 void ForEachSubConnection (TConnectionManipulator f); 652 653 /*!\brief for each connected port, apply the function f */ 654 void ForEachSubConnection (TConstConnectionManipulator f) const; 655 656 657 /*!\brief export a port sub_module_name.port_name as export_name */ 658 bool ExportPort (const std::string &sub_module_name, const std::string &port_name, const std::string &export_name); 659 660 /*!\brief export a config-parameter sub_module_name.config.param_name as export_name */ 661 bool ExportConfig (const std::string &sub_module_name, const std::string ¶m_name, const std::string &export_name); 662 663 /*!\brief export a memory-parameter sub_module_name.memory.param_name as export_name */ 664 bool ExportMemory (const std::string &sub_module_name, const std::string ¶m_name, const std::string &export_name); 665 666 667 /*!\brief save modules, connections, configurations to a stream */ 668 bool WriteToStream (std::ostream &os, const std::string &indent="", bool ext_sto_available=false) const; 669 670 //! see comments of TAgent::LoadFromFile 671 bool LoadFromFile (const std::string &file_name, std::list<std::string> *included_list=NULL); 672 673 674 override void SetNeverAccessed (bool na); 675 676 677 void SetAllSubModuleMode (const TModuleMode &mm); 678 void SetAllSubDebugStream (std::ostream &os); 679 override void SetModuleMode (const TModuleMode &mm) {TModuleInterface::SetModuleMode(mm); SetAllSubModuleMode(mm);} 680 override void SetDebugStream (std::ostream &os) {TModuleInterface::SetDebugStream(os); SetAllSubDebugStream(os);} 681 682 void ShowAllSubModules (const std::string &format="", std::ostream &os=std::cerr) const; 683 684 void ShowAllSubConnections (std::ostream &os=std::cerr) const; 685 686 /*! TEST: export module structure to a graph description language. 687 Draw by graphviz - fdp (e.g. fdp -Tsvg FOO.dot -o BAR.svg) */ 688 void ExportToDOT (std::ostream &os=std::cout) const; 689 690 protected: 691 692 /*! Type of module set (map) whose key is module.InstanceName() */ 693 typedef std::set<TModuleCell> TModuleSet; 694 695 enum TExportKind {ekPort=0, ekConfig, ekMemory}; 696 struct TExportItem 697 { 698 TExportKind Kind; 699 std::string ModuleName; 700 std::string ElemName; 701 std::string ExportName; 702 TExportItem(TExportKind k, const std::string &mname, const std::string &ename, const std::string &xname) 703 : Kind(k), ModuleName(mname), ElemName(ename), ExportName(xname) {} 704 }; 705 706 std::string cmodule_name_; 707 708 TModuleSet sub_modules_; 709 710 std::list<TExportItem> export_list_; //!< stored in Export{Port,Memory,Config} to be used in WriteToStream 711 712 713 inline TModuleInterface* find_sub_module (const std::string &module_name, bool error=false) const; 714 715 /*! remove the module specified by mod_itr. all connections are disconnected */ 716 bool remove_sub_module (TModuleSet::iterator mod_itr); 717 718 bool apply_f_if_to_port_exists (const TPortInfo *from_port, TPortInterface *to_port_ptr, TConnectionManipulator f); 719 bool apply_f_if_to_port_exists_c (const TConstPortInfo *from_port, const TPortInterface *to_port_ptr, TConstConnectionManipulator f) const; 720 721 }; 722 //------------------------------------------------------------------------------------------- 723 724 inline bool operator<(const TCompositeModule::TModuleCell &lhs, const TCompositeModule::TModuleCell &rhs) 725 { 726 return lhs.Name < rhs.Name; 727 } 728 //------------------------------------------------------------------------------------------- 729 730 template <typename t_module> 731 t_module& TCompositeModule::SubModuleAs (const std::string &module_name) 732 { 733 TModuleInterface *m (find_sub_module(module_name,/*error=*/true)); 734 if (m==NULL) {lexit(df); return dummy_return<t_module&>::value();} 735 if (t_module *m2= dynamic_cast<t_module*>(m)) return *m2; 736 LERROR("module "<<module_name<<" is not an instance of "<<t_module::ModuleName()<<"."); 737 lexit(df); return dummy_return<t_module&>::value(); 738 } 739 //------------------------------------------------------------------------------------------- 740 741 template <typename t_module> 742 const t_module& TCompositeModule::SubModuleAs (const std::string &module_name) const 743 { 744 TModuleInterface *m (find_sub_module(module_name,/*error=*/true)); 745 if (m==NULL) {lexit(df); return dummy_return<t_module&>::value();} 746 if (t_module *m2= dynamic_cast<t_module*>(m)) return *m2; 747 LERROR("module "<<module_name<<" is not an instance of "<<t_module::ModuleName()<<"."); 748 lexit(df); return dummy_return<t_module&>::value(); 749 } 750 //------------------------------------------------------------------------------------------- 751 752 //! create a module of the specified type 753 template <typename t_module> 754 t_module& TCompositeModule::AddSubModule (const std::string &v_instance_name) 755 { 756 if (sub_modules_.find(TModuleCell(v_instance_name))!=sub_modules_.end()) 757 { 758 LERROR("module "<<v_instance_name<<" is already registered"); 759 lexit(df); 760 } 761 t_module *p= new t_module (v_instance_name); 762 sub_modules_.insert(TModuleCell(v_instance_name,p,true)); 763 p->SetAgent(Agent()); 764 p->SetParentCModule(this); 765 return *p; 766 } 767 //------------------------------------------------------------------------------------------- 768 769 inline TModuleInterface* TCompositeModule::find_sub_module (const std::string &module_name, bool error) const 770 { 771 TModuleSet::const_iterator itr= sub_modules_.find(module_name); 772 if(itr==sub_modules_.end() || itr->Ptr->IsZombie()) 773 { 774 if(error) LERROR("module "<<module_name<<" is not found."); 775 return NULL; 776 } 777 return itr->Ptr; 778 }; 779 //------------------------------------------------------------------------------------------- 780 781 782 //=========================================================================================== 783 /*!\brief Generator of TCompositeModule */ 784 class TCompositeModuleGenerator 785 //=========================================================================================== 786 { 787 public: 788 789 struct TGeneratorInfo 790 { 791 std::string Script; 792 std::string FileName; //!< filename where Script is defined 793 int LineNum; //!< line number where Script is defined 794 }; 795 796 //! Added: return true, failed: return false 797 bool AddGenerator(const std::string &cmodule_name, const TGeneratorInfo &generator); 798 799 //! Removed: return true, failed: return false 800 bool RemoveGenerator(const std::string &cmodule_name); 801 802 bool GeneratorExists(const std::string &cmodule_name) const; 803 804 const TGeneratorInfo* Generator(const std::string &cmodule_name) const; 805 806 //! Create an instance of cmodule_name; return true for success 807 bool Create(TCompositeModule &instance, const std::string &cmodule_name, const std::string &instance_name, bool no_export=false) const; 808 809 //! Write all composite module definitions to a stream 810 bool WriteToStream (std::ostream &os, const std::string &indent="") const; 811 812 private: 813 814 std::map<std::string, TGeneratorInfo> generators_; 815 std::list<std::string> cmodule_name_list_; //!< list of composite module names (used in WriteToStream) 816 817 }; 818 //------------------------------------------------------------------------------------------- 819 820 821 //=========================================================================================== 822 /*!\brief Function manager */ 823 class TFunctionManager 824 //=========================================================================================== 825 { 826 public: 827 828 struct TFunctionInfo 829 { 830 std::string Script; 831 std::list<std::string> ParamList; 832 std::string FileName; //!< filename where Script is defined 833 int LineNum; //!< line number where Script is defined 834 }; 835 836 //! Added: return true, failed: return false 837 bool AddFunction(const std::string &func_name, const TFunctionInfo &function); 838 839 //! Removed: return true, failed: return false 840 bool RemoveFunction(const std::string &func_name); 841 842 bool FunctionExists(const std::string &func_name) const; 843 844 const TFunctionInfo* Function(const std::string &func_name) const; 845 846 bool ExecuteFunction( 847 const std::string &func_name, const std::list<var_space::TLiteral> &argv, 848 TCompositeModule &context_cmodule, 849 const boost::filesystem::path ¤t_dir, 850 std::list<boost::filesystem::path> *path_list, std::list<std::string> *included_list, 851 TCompositeModuleGenerator *cmp_module_generator, bool no_export=false) const; 852 853 //! Write all function definitions to a stream 854 bool WriteToStream (std::ostream &os, const std::string &indent="") const; 855 856 private: 857 858 std::map<std::string, TFunctionInfo> functions_; 859 860 }; 861 //------------------------------------------------------------------------------------------- 862 863 864 //=========================================================================================== 865 /*!\brief TAgent's Configurations */ 866 struct TAgentConfigurations 867 //=========================================================================================== 868 { 869 std::string DataDir; //!< directoly path to save data (boost::filesystem's portable file-path format) 870 871 std::string LazyLoadModulePattern; /*!< regular expression pattern. if a behavior matches with this, 872 its parameters are saved into the other file, 873 and will loaded when first required */ 874 875 std::string ExtFilePrefix; //!< used in SaveToFile and dump* command to save data in an external file 876 877 TAgentConfigurations(var_space::TVariableMap &mmap) 878 : 879 DataDir ("nonexistent_dir"), 880 LazyLoadModulePattern (""), 881 ExtFilePrefix ("") 882 { 883 #define ADD(x_member) AddToVarMap(mmap, #x_member, x_member) 884 ADD( DataDir ); 885 ADD( LazyLoadModulePattern ); 886 ADD( ExtFilePrefix ); 887 #undef ADD 888 } 889 }; 890 //------------------------------------------------------------------------------------------- 891 892 //=========================================================================================== 893 /*!\brief agent class that holds all instances of the modules */ 894 class TAgent 895 //=========================================================================================== 896 { 897 public: 898 899 //! clear all modules and path_list_ (memories are freed) 900 void Clear(); 901 902 TAgent () 903 : modules_ ("TAgent","global"), 904 conf_ (modules_.ParamBoxConfig().SetMemberMap()), 905 path_list_ (NULL) 906 { 907 modules_.SetAgent(*this); 908 } 909 910 virtual ~TAgent() {} 911 912 913 TCompositeModule& Modules () {return modules_;} 914 const TCompositeModule& Modules () const {return modules_;} 915 916 TModuleInterface& Module (const std::string &module_name) {return modules_.SubModule(module_name);} 917 const TModuleInterface& Module (const std::string &module_name) const {return modules_.SubModule(module_name);} 918 919 /*! search a module named module_name. 920 if a sub-module is a composite one and max_depth>0, module_name is searched recursively */ 921 TModuleInterface* SearchModule (const std::string &module_name, int max_depth=5) {return modules_.SearchSubModule(module_name,max_depth);} 922 /*! search a module named module_name. 923 if a sub-module is a composite one and max_depth>0, module_name is searched recursively */ 924 const TModuleInterface* SearchModule (const std::string &module_name, int max_depth=5) const {return modules_.SearchSubModule(module_name,max_depth);} 925 926 template <typename t_module> 927 t_module& ModuleAs (const std::string &module_name) {return modules_.SubModuleAs<t_module>(module_name);} 928 929 template <typename t_module> 930 const t_module& ModuleAs (const std::string &module_name) const {return modules_.SubModuleAs<t_module>(module_name);} 931 932 //! create a module of the specified type 933 template <typename t_module> 934 t_module& AddModule (const std::string &v_instance_name) {return modules_.AddSubModule<t_module>(v_instance_name);} 935 936 //! create a module whose type is specified by the string v_module_class 937 TModuleInterface& AddModule (const std::string &v_module_class, const std::string &v_instance_name) 938 {return modules_.AddSubModule(v_module_class, v_instance_name);} 939 940 941 /*! connect the two ports. the port types are automatically determined */ 942 bool Connect( 943 TModuleInterface &start_module, const std::string &start_port_name, 944 TModuleInterface &end_module, const std::string &end_port_name) 945 {return modules_.SubConnect(start_module, start_port_name, end_module, end_port_name);} 946 947 /*! connect the two ports. the modules are indicated by names. the port types are automatically determined */ 948 bool Connect( 949 const std::string &start_module_name, const std::string &start_port_name, 950 const std::string &end_module_name, const std::string &end_port_name) 951 {return modules_.SubConnect(start_module_name, start_port_name, end_module_name, end_port_name);} 952 953 /*! disconnect the ports */ 954 bool Disconnect( 955 TModuleInterface &start_module, const std::string &start_port_name, 956 TModuleInterface &end_module, const std::string &end_port_name) 957 {return modules_.SubDisconnect(start_module, start_port_name, end_module, end_port_name);} 958 959 /*! disconnect the ports */ 960 bool Disconnect( 961 const std::string &start_module_name, const std::string &start_port_name, 962 const std::string &end_module_name, const std::string &end_port_name) 963 {return modules_.SubDisconnect(start_module_name, start_port_name, end_module_name, end_port_name);} 964 965 966 const TAgentConfigurations& Config() const {return conf_;} 967 TAgentConfigurations& SetConfig() {return conf_;} 968 969 var_space::TVariable& ParamBoxConfig() {return modules_.ParamBoxConfig();} 970 const var_space::TVariable& ParamBoxConfig() const {return modules_.ParamBoxConfig();} 971 972 973 974 /*!\brief for each module, apply the function f */ 975 void ForEachModule (boost::function<bool(TModuleInterface* module)> f) 976 {modules_.ForEachSubModule(f);} 977 978 /*!\brief for each module, apply the function f */ 979 void ForEachModule (boost::function<bool(const TModuleInterface* module)> f) const 980 {modules_.ForEachSubModule(f);} 981 982 /*!\brief for each connected port, apply the function f */ 983 void ForEachConnection (TCompositeModule::TConnectionManipulator f) 984 {modules_.ForEachSubConnection(f);} 985 986 /*!\brief for each connected port, apply the function f */ 987 void ForEachConnection (TCompositeModule::TConstConnectionManipulator f) const 988 {modules_.ForEachSubConnection(f);} 989 990 991 /*!\brief load modules, connections, configurations from the file [filename] (native path format) 992 \param [in,out]included_list : included full-path (native) list 993 \note If you use include_once for multiple LoadFromFile, the same included_list should be specified */ 994 bool LoadFromFile (const std::string &filename, std::list<std::string> *included_list=NULL); 995 996 /*!\brief save modules, connections, configurations to the file [filename] (native path format) */ 997 bool SaveToFile (const std::string &filename, const std::string &ext_file_prefix="") const; 998 999 1000 /*!\brief add dir_name (native format path) to the path-list */ 1001 void AddPath (const std::string &dir_name); 1002 1003 /*!\brief add dir_list (list of native format path) to the path-list */ 1004 void AddPathList (const std::list<std::string> &dir_list); 1005 1006 std::list<boost::filesystem::path>* PathListPtr() {return path_list_;} 1007 const std::list<boost::filesystem::path>* PathListPtr() const {return path_list_;} 1008 std::list<boost::filesystem::path>& SetPathList(); 1009 1010 1011 TCompositeModuleGenerator& CompositeModuleGenerator() {return cmp_module_generator_;} 1012 const TCompositeModuleGenerator& CompositeModuleGenerator() const {return cmp_module_generator_;} 1013 TFunctionManager& FunctionManager() {return function_manager_;} 1014 const TFunctionManager& FunctionManager() const {return function_manager_;} 1015 1016 bool ExecuteFunction( 1017 const std::string &func_name, const std::list<var_space::TLiteral> &argv, 1018 TCompositeModule &context_cmodule, bool no_export=false); 1019 1020 bool ExecuteScript( 1021 const std::string &exec_script, TCompositeModule &context_cmodule, std::list<std::string> *included_list=NULL, 1022 const std::string &file_name="-", int start_line_num=1, bool no_export=false); 1023 1024 /*!\brief search filename from the path-list, return the native path 1025 \param [in]omissible_extension : indicate an extension with dot, such as ".agent" */ 1026 std::string SearchFileName (const std::string &filename, const std::string &omissible_extension="."SKYAI_DEFAULT_AGENT_SCRIPT_EXT) const; 1027 1028 /*!\brief return a complete native path to filename which is a relative path from conf_.DataDir */ 1029 std::string GetDataFileName (const std::string &filename) const; 1030 1031 1032 /*!\brief chech module_name matches with the conf_.LazyLoadModulePattern */ 1033 bool IsLazyLoadModule (const std::string &module_name) const; 1034 1035 1036 /*!\brief write all port information (port kind, port pointer, every outer module name and port name) to os */ 1037 void DumpPortInfo (std::ostream &os=std::cerr) const; 1038 1039 void SetAllModuleMode (const TModuleInterface::TModuleMode &mm) 1040 {modules_.SetModuleMode(mm);} 1041 void SetAllDebugStream (std::ostream &os) 1042 {modules_.SetDebugStream(os);} 1043 1044 void ShowAllModules (const std::string &format="", std::ostream &os=std::cerr) const 1045 {modules_.ShowAllSubModules(format,os);} 1046 1047 void ShowAllConnections (std::ostream &os=std::cerr) const 1048 {modules_.ShowAllSubConnections(os);} 1049 1050 /*! TEST: export module structure to a graph description language. 1051 Draw by graphviz - fdp (e.g. fdp -Tsvg FOO.dot -o BAR.svg) */ 1052 void ExportToDOT (std::ostream &os=std::cout) const 1053 {modules_.ExportToDOT(os);} 1054 1055 1056 protected: 1057 1058 //! forbit to call a copy constructor 1059 TAgent (const TAgent&); 1060 const TAgent& operator=(const TAgent&); 1061 1062 TCompositeModule modules_; 1063 1064 TAgentConfigurations conf_; 1065 1066 TCompositeModuleGenerator cmp_module_generator_; 1067 TFunctionManager function_manager_; 1068 1069 std::list<boost::filesystem::path> *path_list_; 1070 1071 }; 1072 //------------------------------------------------------------------------------------------- 1073 1074 1075 //=========================================================================================== 1076 // implementation of inline member functions 1077 //=========================================================================================== 1078 1079 inline void TPortInterface::first_call_check() const 1080 { 1081 if (never_called_) 1082 { 1083 outer_base_.first_access_check(); 1084 never_called_= false; 1085 } 1086 } 1087 //------------------------------------------------------------------------------------------- 1088 1089 inline void TModuleInterface::first_access_check() const 1090 { 1091 if (!never_accessed_) return; 1092 never_accessed_= false; 1093 if (parent_cmodule_) parent_cmodule_->first_access_check(); 1094 1095 const_cast<TModuleInterface*>(this)->on_first_access(); 1096 } 1097 //------------------------------------------------------------------------------------------- 1098 1099 1100 //------------------------------------------------------------------------------------------- 1101 } // end of namespace loco_rabbits 1102 //------------------------------------------------------------------------------------------- 1103 #endif // skyai_base_h 1104 //-------------------------------------------------------------------------------------------