00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033 #include "Sim/Foundation/Resource/ResourceNode.h"
00034
00035 using namespace Onikiri;
00036
00037 PhysicalResourceNode::PhysicalResourceNode()
00038 {
00039 m_typeConverter = NULL;
00040 m_rid = RID_INVALID;
00041 m_initialized = false;
00042 m_totalEntryCount = 0;
00043 m_connectedEntryCount = 0;
00044 }
00045
00046 PhysicalResourceNode::~PhysicalResourceNode()
00047 {
00048 if( !IsParameterReleased() ){
00049 THROW_RUNTIME_ERROR(
00050 "'ReleaseParam()' was not called in the node '%s'.\n"
00051 "A class inherited from the 'PhysicalResourceNode' "
00052 "must call 'ReleaseParam()' before its destruction."
00053 "This method call can not be automated, "
00054 "because the destructor of the 'PhysicalResourceNode' "
00055 "can not touch the member of the inherited class.",
00056 m_info.name.c_str()
00057 );
00058 }
00059
00060 }
00061
00062 void PhysicalResourceNode::ReleaseParam()
00063 {
00064 PhysicalResourceNode::ProcessParamMap(true);
00065 ParamExchange::ReleaseParam();
00066 }
00067
00068 void PhysicalResourceNode::SetInfo( const PhysicalResourceNodeInfo& info )
00069 {
00070 m_initialized = true;
00071 m_info = info;
00072 if( info.name == "" ||
00073 info.typeName == "" ||
00074 info.paramPath.ToString() == "" ||
00075 info.resultPath.ToString() == "" ||
00076 info.resultRootPath.ToString() == ""
00077 ){
00078 THROW_RUNTIME_ERROR( "The passed info is invalid." );
00079 }
00080 m_who = GetName() + "(" + GetTypeName() + ")";
00081 }
00082
00083 const PhysicalResourceNodeInfo& PhysicalResourceNode::GetInfo()
00084 {
00085 return m_info;
00086 }
00087
00088 const char* PhysicalResourceNode::Who() const
00089 {
00090 return m_who.c_str();
00091 }
00092
00093 const String& PhysicalResourceNode::GetName() const
00094 {
00095 return m_info.name;
00096 }
00097
00098 const String& PhysicalResourceNode::GetTypeName() const
00099 {
00100 return m_info.typeName;
00101 }
00102
00103 const ParamXMLPath& PhysicalResourceNode::GetParamPath() const
00104 {
00105 if( !m_initialized ){
00106 THROW_RUNTIME_ERROR(
00107 "This physical resource is not initialized. "
00108 "Does call LoadParam() in a constructor? "
00109 "LoadParam() must be called in or after INIT_PRE_CONNECTION phase."
00110 );
00111 }
00112
00113 return m_info.paramPath;
00114 }
00115
00116 const ParamXMLPath& PhysicalResourceNode::GetResultPath() const
00117 {
00118 if( !m_initialized ){
00119 THROW_RUNTIME_ERROR(
00120 "This physical resource is not initialized. "
00121 "This error here may simply mean LoadParam() is called in a constructor. "
00122 "LoadParam() must be called in or after INIT_PRE_CONNECTION phase."
00123 );
00124 }
00125
00126 return m_info.resultPath;
00127 }
00128
00129 const ParamXMLPath& PhysicalResourceNode::GetResultRootPath() const
00130 {
00131 return m_info.resultRootPath;
00132 }
00133
00134 void PhysicalResourceNode::SetTypeConverter( ResourceTypeConverterIF* converter )
00135 {
00136 m_typeConverter = converter;
00137 }
00138
00139
00140 void PhysicalResourceNode::CheckConnection(
00141 PhysicalResourceBaseArray& srcArray,
00142 const String& to,
00143 const ResourceConnectionResult& result
00144 ){
00145 if( srcArray.GetSize() == 0 ){
00146 THROW_RUNTIME_ERROR(
00147 "The passed resource array has no entry."
00148 );
00149 }
00150
00151 PhysicalResourceNode* res = srcArray[0];
00152
00153 if( result.connectedCount == 0 ){
00154 const char* srcName = res->m_info.name.c_str();
00155 const char* toName = (to == "") ? srcName : to.c_str();
00156 const char* nodeName = m_info.name.c_str();
00157 THROW_RUNTIME_ERROR(
00158 "Could not connect '%s' to '%s' in '%s'. "
00159 "Does '%s' has a member '%s'?",
00160 srcName, toName, nodeName,
00161 nodeName, toName
00162 );
00163 }
00164 else if( result.connectedCount > 1 ){
00165 THROW_RUNTIME_ERROR(
00166 "The node '%s' is connected to the node '%s' more than once.\n"
00167 "Use 'Connection' and specify a name ('To' attribute) that the node is connected to.",
00168 res->m_info.name.c_str(),
00169 m_info.name.c_str()
00170 );
00171 }
00172
00173 m_totalEntryCount = result.entryCount;
00174 m_connectedEntryCount++;
00175 }
00176
00177
00178 void PhysicalResourceNode::CheckNodeIsScalar(
00179 PhysicalResourceBaseArray& srcArray,
00180 const String& targetName,
00181 const String& orgName
00182 ){
00183 if( srcArray.GetSize() != 1 ){
00184 THROW_RUNTIME_ERROR(
00185 "Cannot connect the array node '%s' to the scalar node '%s.%s'.\n"
00186 "Maybe you set a thread count that is less than a core count.\n"
00187 "A thread count is 'total' thread count in all cores, and "
00188 "a thread count is always bigger or equal to core count.",
00189 orgName.c_str(),
00190 m_info.name.c_str(),
00191 targetName.c_str()
00192 );
00193 }
00194 }
00195
00196
00197 ResourceConnectionResult PhysicalResourceNode::ConnectResource(
00198 PhysicalResourceBaseArray& srcArray,
00199 const String& orgName,
00200 const String& to,
00201 bool chained
00202 ){
00203
00204
00205
00206
00207 THROW_RUNTIME_ERROR(
00208 "Invalid connection.\nThe resource map is not defined in the '%s'.",
00209 m_info.typeName.c_str()
00210 );
00211
00212
00213
00214
00215
00216
00217
00218 return ResourceConnectionResult();
00219 }
00220
00221
00222 void PhysicalResourceNode::ValidateConnection()
00223 {
00224 if( m_connectedEntryCount < m_totalEntryCount ){
00225 const char* name = m_info.name.c_str();
00226 THROW_RUNTIME_ERROR( "There are resouce members that are not connected correctly in %s.", name );
00227 }
00228 }