src/Sim/Foundation/Resource/ResourceNode.h

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #ifndef SIM_FOUNDATION_RESOUCE_RESOURCE_NODE_H
00033 #define SIM_FOUNDATION_RESOUCE_RESOURCE_NODE_H
00034 
00035 #include "Types.h"
00036 #include "Sim/Foundation/Resource/ResourceBase.h"
00037 #include "Sim/Foundation/Resource/ResourceArray.h"
00038 #include "Env/Param/ParamExchange.h"
00039 
00040 namespace Onikiri 
00041 {
00042     //
00043     // --- Macros for resource map 
00044     //
00045 
00046     struct ResourceConnectionResult
00047     {
00048         int connectedCount;
00049         int entryCount;
00050         ResourceConnectionResult() :
00051             connectedCount(0),
00052             entryCount(0)
00053         {
00054         }
00055 
00056         void Add( const ResourceConnectionResult& rhs )
00057         {
00058             connectedCount  += rhs.connectedCount;
00059             entryCount      += rhs.entryCount;
00060         }
00061     };
00062 
00063     #define BEGIN_RESOURCE_MAP() \
00064         ResourceConnectionResult \
00065             ConnectResource( PhysicalResourceBaseArray& srcArray, const String& srcName, const String& to, bool chained ) \
00066         { \
00067             return ConnectResourceBody( *this, srcArray, srcName, to, chained ); \
00068         } \
00069         template <typename ClassType> \
00070         ResourceConnectionResult \
00071             ConnectResourceBody( ClassType& refThis, PhysicalResourceBaseArray& srcArray, const String& srcName, const String& to, bool chained ) \
00072         { \
00073             ResourceConnectionResult result; \
00074 
00075     #define END_RESOURCE_MAP() \
00076             if(!chained) \
00077                 CheckConnection( srcArray, to, result ); \
00078             return result;\
00079         }
00080 
00081     #define RESOURCE_OPTIONAL_ENTRY( typeName, dstName, resEntry ) \
00082         ConnectResourceEntry<typeName>( resEntry, srcArray, #typeName, dstName, srcName, to, &result ); \
00083 
00084     #define RESOURCE_ENTRY( typeName, dstName, resEntry ) \
00085         RESOURCE_OPTIONAL_ENTRY( typeName, dstName, resEntry ) \
00086         result.entryCount++;
00087 
00088     #define CHAIN_BASE_RESOURCE_MAP( classType ) \
00089         result.Add( classType::ConnectResource( srcArray, srcName, to, true ) );
00090 
00091     // Setter prototype : 
00092     // setter( const PhysicalResourceArray< ValueType >& array );
00093     // setter( const ValueType* scalar );
00094     #define RESOURCE_OPTIONAL_SETTER_ENTRY( typeName, dstName, setter ) \
00095         ConnectResourceEntry<ClassType, typeName>( &ClassType::setter, srcArray, #typeName, dstName, srcName, to, &result ); \
00096 
00097     #define RESOURCE_SETTER_ENTRY( typeName, dstName, setter ) \
00098         RESOURCE_OPTIONAL_SETTER_ENTRY( typeName, dstName, setter ) \
00099         result.entryCount++;
00100 
00101 
00102     // This class is an interface for dynamic_cast with a type name string 'typeName'.
00103     // We can not use original 'dynamic_cast' in this situation,  
00104     // because the dynamic_cast can not cast an incomplete type declared by forward declaration.
00105     class ResourceTypeConverterIF
00106     {
00107     public:
00108         virtual ~ResourceTypeConverterIF(){};
00109         virtual void* DynamicCast(const String& typeName, PhysicalResourceIF* orgPtr) = 0;
00110     };
00111 
00112     // Node information 
00113     struct PhysicalResourceNodeInfo
00114     {
00115         String typeName;
00116         String name;
00117         ParamXMLPath paramPath;
00118         ParamXMLPath resultRootPath;
00119         ParamXMLPath resultPath;
00120     };
00121 
00122     // A base class for a physical resource node of the 'ResourceBuilder' system.
00123     class PhysicalResourceNode : 
00124         public PhysicalResourceBase,
00125         public ParamExchange
00126     {
00127     protected:
00128         bool m_initialized;
00129         PhysicalResourceNodeInfo m_info;
00130         ResourceTypeConverterIF* m_typeConverter;
00131         String m_who;
00132         int m_totalEntryCount;
00133         int m_connectedEntryCount;
00134 
00135         typedef
00136             PhysicalResourceArray<PhysicalResourceNode>
00137             PhysicalResourceBaseArray;
00138 
00139         // Copy the instances of the type 'typeName' from 'srcArray' to 'resArray'.
00140         template <typename ArrayValueType>
00141         void CopyResourceArray(
00142             const String& typeName,
00143             PhysicalResourceArray<ArrayValueType>& resArray,
00144             PhysicalResourceBaseArray& srcArray )
00145         {
00146             resArray.Resize( srcArray.GetSize() );
00147             for( int i = 0; i < srcArray.GetSize(); i++ ){
00148                 ArrayValueType* res;
00149                 DynamicCast( &res, typeName, srcArray[i] );
00150                 if(!res){
00151                     THROW_RUNTIME_ERROR( "dynamic cast failed." );
00152                 }
00153 
00154                 resArray[i] = res;
00155             }
00156         }
00157 
00158         // Connect resources
00159         // This method is used for connecting an array.
00160         template <typename ArrayValueType>
00161         void ConnectResourceEntry( 
00162             PhysicalResourceArray<ArrayValueType>& resArray,
00163             PhysicalResourceBaseArray& srcArray, 
00164             const char* typeName,
00165             const char* dstName,
00166             const String& srcName,
00167             const String& to,
00168             ResourceConnectionResult* result 
00169         ){
00170             ASSERT( srcArray.GetSize() > 0 );
00171 
00172             ArrayValueType* res;
00173             DynamicCast( &res, typeName, srcArray[0] );
00174 
00175             // Test dynamic cast and names
00176             if( res && ( (to == "" && srcName == dstName ) || to == dstName ) ){
00177                 CopyResourceArray( typeName, resArray, srcArray );
00178                 result->connectedCount++;
00179             }
00180         }
00181 
00182         // Connect resource
00183         // This method is used for connecting scalar.
00184         template <typename ArrayValueType>
00185         void ConnectResourceEntry( 
00186             ArrayValueType*& resEntry,
00187             PhysicalResourceBaseArray& srcArray, 
00188             const char* typeName,
00189             const char* dstName,
00190             const String& srcName,
00191             const String& to,
00192             ResourceConnectionResult* result 
00193         ){
00194             ASSERT( srcArray.GetSize() > 0 );
00195 
00196             ArrayValueType* res;
00197             DynamicCast( &res, typeName, srcArray[0] );
00198 
00199             // Test dynamic cast and names
00200             if( res && ( (to == "" && srcName == dstName ) || to == dstName ) ){
00201                 CheckNodeIsScalar( srcArray, dstName, srcName );
00202                 resEntry = res;
00203                 result->connectedCount++;
00204             }
00205         }
00206 
00207         // Connect resources by using the setter method
00208         template <typename ClassType, typename ArrayValueType>
00209         void ConnectResourceEntry( 
00210             void (ClassType::*setter)( PhysicalResourceArray<ArrayValueType>& ),
00211             PhysicalResourceBaseArray& srcArray, 
00212             const char* typeName,
00213             const char* dstName,
00214             const String& srcName,
00215             const String& to, 
00216             ResourceConnectionResult* result 
00217         ){
00218             ASSERT( srcArray.GetSize() > 0 );
00219 
00220             ArrayValueType* res;
00221             DynamicCast( &res, typeName, srcArray[0] );
00222 
00223             // Test dynamic cast and names
00224             if( res && ( (to == "" && srcName == dstName ) || to == dstName ) ){
00225 
00226                 PhysicalResourceArray<ArrayValueType> resArray;
00227                 CopyResourceArray( typeName, resArray, srcArray );
00228 
00229                 // Call the setter by using the pointer of the derived class.
00230                 (dynamic_cast<ClassType*>(this)->*setter)( resArray );
00231 
00232                 result->connectedCount++;
00233             }
00234         }
00235 
00236         // Connect resources by using the setter method
00237         template <typename ClassType, typename ArrayValueType>
00238         void ConnectResourceEntry( 
00239             void (ClassType::*setter)( ArrayValueType* ),
00240             PhysicalResourceBaseArray& srcArray, 
00241             const char* typeName,
00242             const char* dstName,
00243             const String& srcName,
00244             const String& to, 
00245             ResourceConnectionResult* result 
00246         ){
00247             ASSERT( srcArray.GetSize() > 0 );
00248 
00249             ArrayValueType* res;
00250             DynamicCast( &res, typeName, srcArray[0] );
00251 
00252             // Test dynamic cast and names
00253             if( res && ( (to == "" && srcName == dstName ) || to == dstName ) ){
00254                 CheckNodeIsScalar( srcArray, dstName, srcName );
00255                 // Call the setter by using the pointer of the derived class.
00256                 (dynamic_cast<ClassType*>(this)->*setter)( res );   
00257                 result->connectedCount++;
00258             }
00259         }
00260 
00261         // Dynamic cast wrapper
00262         template <typename T>
00263         void DynamicCast( 
00264             T**ptr,
00265             const String& typeName,
00266             PhysicalResourceNode* orgPtr )
00267         {
00268             if(!m_typeConverter){
00269                 THROW_RUNTIME_ERROR( "A resource type converter is not set." );
00270             }
00271 
00272             *ptr = 
00273                 static_cast<T*>(
00274                     m_typeConverter->DynamicCast( typeName, orgPtr )
00275                 );
00276         };
00277 
00278         void CheckConnection(
00279             PhysicalResourceBaseArray& res,
00280             const String& to,
00281             const ResourceConnectionResult& result 
00282         );
00283         
00284         void CheckNodeIsScalar( 
00285             PhysicalResourceBaseArray& srcArray,
00286             const String& dstName,
00287             const String& srcName
00288         );
00289 
00290         template <class T>
00291         void CheckNodeInitialized( 
00292             const String& nodeName,
00293             T* resPtr
00294         ){
00295             if( resPtr == 0 ){
00296                 THROW_RUNTIME_ERROR(
00297                     "'%s.%s' is not set.",
00298                     m_info.name.c_str(),
00299                     nodeName.c_str()
00300                 );
00301             }
00302         }
00303 
00304         template <class T>
00305         void CheckNodeInitialized( 
00306             const String& nodeName,
00307             PhysicalResourceArray<T>& resArray
00308         ){
00309             if( resArray.GetSize() == 0 ){
00310                 THROW_RUNTIME_ERROR(
00311                     "'%s.%s' is not set.",
00312                     m_info.name.c_str(),
00313                     nodeName.c_str()
00314                 );
00315             }
00316         }
00317 
00318         BEGIN_PARAM_MAP( "" )
00319             BEGIN_PARAM_PATH( GetResultRootPath() )
00320                 PARAM_ENTRY( "@Name", m_info.name )
00321             END_PARAM_PATH()
00322             BEGIN_PARAM_PATH( GetResultPath() )
00323                 PARAM_ENTRY( "@RID",  m_rid );
00324             END_PARAM_PATH()
00325         END_PARAM_MAP()
00326 
00327     public:
00328         PhysicalResourceNode();
00329         ~PhysicalResourceNode();
00330 
00331         void SetInfo( const PhysicalResourceNodeInfo& info );
00332         const PhysicalResourceNodeInfo& GetInfo();
00333         
00334         const char* Who() const;
00335 
00336         const String& GetName() const;
00337         const String& GetTypeName() const;
00338         const ParamXMLPath& GetParamPath() const;
00339         const ParamXMLPath& GetResultPath() const;
00340         const ParamXMLPath& GetResultRootPath() const;
00341 
00342         void SetTypeConverter( ResourceTypeConverterIF* );
00343 
00344         void ReleaseParam();
00345 
00346         // This method must be defined in the BEGIN_RESOURCE_MAP macro.
00347         virtual ResourceConnectionResult ConnectResource(
00348             PhysicalResourceBaseArray& srcArray, 
00349             const String& srcName, 
00350             const String& to,
00351             bool chained
00352         );
00353 
00354         // Initializing phase
00355         enum InitPhase
00356         {
00357             // After constructing and before object connection.
00358             // ParamExchange::LoadParam() must be called in this phase or later.
00359             INIT_PRE_CONNECTION,    
00360 
00361             // After connection
00362             INIT_POST_CONNECTION
00363         };
00364 
00365         virtual void Initialize(InitPhase phase) = 0;
00366 
00367         // This method is called just before all nodes are destructed.
00368         // In this timing, all nodes are still alive.
00369         virtual void Finalize(){};
00370 
00371         // This method is called when a simulation mode is changed.
00372         enum SimulationMode
00373         {
00374             SM_EMULATION,
00375             SM_INORDER,
00376             SM_SIMULATION
00377         };
00378         virtual void ChangeSimulationMode( SimulationMode mode ){};
00379 
00380         // Validate connection.
00381         void ValidateConnection();
00382     };
00383 
00384 }; // namespace Onikiri
00385 
00386 #endif // SIM_FOUNDATION_RESOUCE_RESOURCE_NODE_H
00387 
00388 

Onikiri2に対してTue Jun 18 14:34:23 2013に生成されました。  doxygen 1.4.7