| |
libFAUDES
Sections
Index
|
rtiregistry.cppGo to the documentation of this file.00001 /** @file rtiregistry.cpp Runtime interface, registry for faudes types and functions */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2009 Ruediger Berndt 00006 Copyright (C) 2009 Thomas Moor 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00021 00022 00023 00024 #include "rtiregistry.h" 00025 #include "rtiwrapper.h" 00026 #include "corefaudes.h" 00027 #include "allplugins.h" 00028 00029 // auto install types 00030 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00031 #include "rtiautoload.h" 00032 #include "rtiautoload.cpp" 00033 #endif 00034 00035 namespace faudes{ 00036 00037 00038 00039 /* 00040 ******************************************************************** 00041 ******************************************************************** 00042 ******************************************************************** 00043 00044 Implemantation of faudes TypeRegistry 00045 00046 ******************************************************************** 00047 ******************************************************************** 00048 ******************************************************************** 00049 */ 00050 00051 // static members: ref to the only one instnace 00052 TypeRegistry* TypeRegistry::mpInstance = 0; 00053 00054 // static member: access to signleton 00055 TypeRegistry* TypeRegistry::G(){ 00056 // lazy initialization 00057 if(!mpInstance){ 00058 FD_DRTI("TypeRegistry::G(): Constrtuct singleton"); 00059 mpInstance = new TypeRegistry(); 00060 } 00061 return(mpInstance); 00062 } 00063 00064 // clear all 00065 void TypeRegistry::Clear(){ 00066 // delete all typedefs contained in map 00067 std::map<std::string, TypeDefinition*>::iterator mit; 00068 for(mit = mNameToTypeDef.begin(); mit != mNameToTypeDef.end(); mit++){ 00069 if(mit->second != NULL){ 00070 delete mit->second; 00071 mit->second = NULL; 00072 } 00073 } 00074 // delete maps 00075 mNameToTypeDef.clear(); 00076 mIdToTypeDef.clear(); 00077 } 00078 00079 // query number of entries 00080 int TypeRegistry::Size() const{ 00081 return(mNameToTypeDef.size()); 00082 } 00083 00084 // read access on type map 00085 TypeRegistry::Iterator TypeRegistry::Begin(void) const{ 00086 return(mNameToTypeDef.begin()); 00087 } 00088 00089 // read access on type map 00090 TypeRegistry::Iterator TypeRegistry::End(void) const{ 00091 return(mNameToTypeDef.end()); 00092 } 00093 00094 // insert new entry 00095 void TypeRegistry::Insert(TypeDefinition* pTypeDef){ 00096 FD_DRTI("TypeRegistration::Insert(): definition for " << pTypeDef->Name()); 00097 // test existence 00098 if(Exists(pTypeDef->Name())){ 00099 std::stringstream err; 00100 err << "Cannot overwrite existing entry with type " << pTypeDef->Name() << std::endl; 00101 throw Exception("TypeRegistry::Insert()", err.str(), 46); 00102 } 00103 // record in main map 00104 mNameToTypeDef[pTypeDef->Name()]=pTypeDef; 00105 // record in id map 00106 if(pTypeDef->Prototype()) 00107 mIdToTypeDef[typeid(*(pTypeDef->Prototype())).name()]=pTypeDef; 00108 } 00109 00110 00111 // scan token stream for type definitions 00112 void TypeRegistry::MergeDocumentation(TokenReader& rTr) { 00113 FD_DRTI("TypeRegistration::MergeMergeDocumentation()"); 00114 // scan file 00115 Token token; 00116 while(rTr.Peek(token)) { 00117 // continue on other tokens 00118 if(token.Type()!=Token::Begin) { rTr.Get(token); continue; } 00119 if(token.StringValue()!="TypeDefinition") { rTr.Get(token); continue; } 00120 // found type def in file 00121 rTr.ReadBegin("TypeDefinition"); 00122 rTr.Peek(token); 00123 std::string ftype=token.StringValue(); 00124 // extract type name 00125 size_t pos=ftype.find("::"); 00126 if(pos!=std::string::npos) ftype=ftype.substr(pos+2); 00127 // locate type def in map 00128 Iterator tit = mNameToTypeDef.find(ftype); 00129 // case 1: type exists: add documentaion 00130 if(tit!=mNameToTypeDef.end()) { 00131 tit->second->MergeDocumentationBody(rTr); 00132 rTr.ReadEnd("TypeDefinition"); 00133 continue; 00134 } 00135 // case 2: type does not exist: insert fake entry 00136 TypeDefinition* tdef = new TypeDefinition(ftype); 00137 tdef->MergeDocumentationBody(rTr); 00138 Insert(tdef); 00139 rTr.ReadEnd("TypeDefinition"); 00140 } 00141 } 00142 00143 // scan file for type definitions 00144 void TypeRegistry::MergeDocumentation(const std::string& rFileName) { 00145 TokenReader tr(rFileName); 00146 MergeDocumentation(tr); 00147 } 00148 00149 00150 // construct faudes object by typename 00151 Type* TypeRegistry::NewObject(const std::string& rName) const{ 00152 FD_DRTI("TypeRegistry::NewObject(\"" << rName << "\")"); 00153 Iterator mit=mNameToTypeDef.find(rName); 00154 if(mit == End()) { 00155 std::stringstream err; 00156 err << "Unknown Type " << rName << std::endl; 00157 throw Exception("TypeRegistry::NewObject()", err.str(), 47); 00158 } 00159 Type* res=mit->second->NewObject(); 00160 if(!res) { 00161 std::stringstream err; 00162 err << "Failed to instatiate new " << rName << std::endl; 00163 throw Exception("TypeRegistry::NewObject()", err.str(), 47); 00164 } 00165 return res; 00166 } 00167 00168 // construct faudes object by typed reference 00169 Type* TypeRegistry::NewObject(const Type& rType) const{ 00170 FD_DRTI("TypeRegistry::NewObject(prototype): typeid " << typeid(rType).name()); 00171 Iterator mit; 00172 mit=mIdToTypeDef.find(typeid(rType).name()); 00173 if(mit == mIdToTypeDef.end()) { 00174 std::stringstream err; 00175 err << "Unknown type by reference" << std::endl; 00176 throw Exception("TypeRegistry::NewObject()", err.str(), 47); 00177 } 00178 return(rType.New()); 00179 } 00180 00181 // access type definition by type name 00182 const TypeDefinition& TypeRegistry::Definition(const std::string& rName) const{ 00183 FD_DRTI("TypeRegistry::Definition( " << rName << " )"); 00184 Iterator mit=mNameToTypeDef.find(rName); 00185 if(mit == End()) { 00186 std::stringstream err; 00187 err << "Type not found: \"" << rName << "\""; 00188 throw Exception("TypeRegistry::Definition()", err.str(), 46); 00189 } 00190 return(*(mit->second)); 00191 } 00192 00193 // access type definition by typed reference 00194 const TypeDefinition& TypeRegistry::Definition(const Type& rType) const{ 00195 FD_DRTI("TypeRegistry::Definition(): typeid " << typeid(rType).name()); 00196 Iterator mit; 00197 mit=mIdToTypeDef.find(typeid(rType).name()); 00198 if(mit!=mIdToTypeDef.end()) return *(mit->second); 00199 std::stringstream err; 00200 err << "Type not found: " << typeid(rType).name(); 00201 throw Exception("TypeRegistry::Definition()", err.str(), 46); 00202 } 00203 00204 // access type definition by typed reference 00205 const std::string& TypeRegistry::TypeName(const Type& rType) const{ 00206 FD_DRTI("TypeRegistry::TypeName(): typeid " << typeid(rType).name()); 00207 Iterator mit; 00208 mit=mIdToTypeDef.find(typeid(rType).name()); 00209 if(mit!=mIdToTypeDef.end()) return mit->second->Name(); 00210 static std::string empty(""); 00211 return empty; 00212 } 00213 00214 // test existsnce by type name 00215 bool TypeRegistry::Exists(const std::string& rName) const{ 00216 return mNameToTypeDef.find(rName) != End(); 00217 } 00218 00219 // test existsnce by type name 00220 bool TypeRegistry::Exists(const Type& rType) const{ 00221 return mIdToTypeDef.find(typeid(rType).name()) != mIdToTypeDef.end(); 00222 } 00223 00224 00225 // token write (informative/debugging) 00226 void TypeRegistry::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00227 FD_DRTI("TypeRegistry::DoWrite(): file " << rTw.FileName()); 00228 // ignore label and context 00229 (void) rLabel; 00230 (void) pContext; 00231 // doit 00232 rTw.WriteBegin("TypeRegistry"); 00233 Iterator tit; 00234 for(tit=Begin();tit!=End();tit++) { 00235 // write type definition 00236 tit->second->Write(rTw); 00237 } 00238 rTw.WriteEnd("TypeRegistry"); 00239 } 00240 00241 00242 /* 00243 ******************************************************************** 00244 ******************************************************************** 00245 ******************************************************************** 00246 00247 Implemantation of faudes FunctionRegistry 00248 00249 ******************************************************************** 00250 ******************************************************************** 00251 ******************************************************************** 00252 */ 00253 00254 // static members: ref to the only one instnace 00255 FunctionRegistry* FunctionRegistry::mpInstance = 0; 00256 00257 // static member: access to signleton 00258 FunctionRegistry* FunctionRegistry::G(){ 00259 // lazy initialization 00260 if(!mpInstance){ 00261 FD_DRTI("FunctionRegistry::G(): Construct singleton"); 00262 mpInstance = new FunctionRegistry(); 00263 } 00264 return(mpInstance); 00265 } 00266 00267 // clear all 00268 void FunctionRegistry::Clear(){ 00269 // delete all functiondefs contained in map 00270 std::map<std::string, FunctionDefinition*>::iterator mit; 00271 for(mit = mNameToFunctionDef.begin(); mit != mNameToFunctionDef.end(); mit++){ 00272 if(mit->second != NULL) { 00273 FD_DRTI("FunctionRegistry::Clear: removing " << mit->second->Name()); 00274 delete mit->second; 00275 mit->second = NULL; 00276 } 00277 } 00278 // delete maps 00279 mNameToFunctionDef.clear(); 00280 mIdToFunctionDef.clear(); 00281 } 00282 00283 // query number of entries 00284 int FunctionRegistry::Size() const{ 00285 return(mNameToFunctionDef.size()); 00286 } 00287 00288 // read access on function map 00289 FunctionRegistry::Iterator FunctionRegistry::Begin(void) const{ 00290 return(mNameToFunctionDef.begin()); 00291 } 00292 00293 // read access on function map 00294 FunctionRegistry::Iterator FunctionRegistry::End(void) const{ 00295 return(mNameToFunctionDef.end()); 00296 } 00297 00298 // insert new entry 00299 void FunctionRegistry::Insert(FunctionDefinition* pFunctionDef){ 00300 FD_DRTI("FunctionRegistration::Insert(): definition for " << pFunctionDef->Name()); 00301 // test existence 00302 if(Exists(pFunctionDef->Name())){ 00303 std::stringstream err; 00304 err << "Cannot overwrite existing entry with function " << pFunctionDef->Name() << std::endl; 00305 throw Exception("FunctionRegistry::Insert()", err.str(), 46); 00306 } 00307 // record in map 00308 mNameToFunctionDef[pFunctionDef->Name()]=pFunctionDef; 00309 // record in id map 00310 if(pFunctionDef->Prototype()) 00311 mIdToFunctionDef[typeid(*(pFunctionDef->Prototype())).name()]=pFunctionDef; 00312 } 00313 00314 00315 // scan token stream for function definitions 00316 void FunctionRegistry::MergeDocumentation(TokenReader& rTr) { 00317 FD_DRTI("FunctionRegistration::MergeDocumentation()"); 00318 // scan file 00319 Token token; 00320 while(rTr.Peek(token)) { 00321 // continue on other tokens 00322 if(token.Type()!=Token::Begin) { rTr.Get(token); continue; } 00323 if(token.StringValue()!="FunctionDefinition") { rTr.Get(token); continue; } 00324 // found function def in file 00325 rTr.ReadBegin("FunctionDefinition"); 00326 rTr.Peek(token); 00327 std::string ffunction=token.StringValue(); 00328 // extract function name 00329 size_t pos=ffunction.find("::"); 00330 if(pos!=std::string::npos) ffunction=ffunction.substr(pos+2); 00331 // locate function def in map 00332 Iterator fit = mNameToFunctionDef.find(ffunction); 00333 // case 1: function exists: add documentaion 00334 if(fit!=mNameToFunctionDef.end()) { 00335 fit->second->MergeDocumentationBody(rTr); 00336 rTr.ReadEnd("FunctionDefinition"); 00337 continue; 00338 } 00339 // case 2: function does not exist: insert fake entry 00340 FunctionDefinition* fdef = new FunctionDefinition(ffunction); 00341 fdef->MergeDocumentationBody(rTr); 00342 Insert(fdef); 00343 rTr.ReadEnd("FunctionDefinition"); 00344 } 00345 } 00346 00347 // scan file for function definitions 00348 void FunctionRegistry::MergeDocumentation(const std::string& rFileName) { 00349 TokenReader tr(rFileName); 00350 MergeDocumentation(tr); 00351 } 00352 00353 00354 // construct faudes object by functionname 00355 Function* FunctionRegistry::NewFunction(const std::string& rName) const{ 00356 FD_DRTI("FunctionRegistry::NewFunction(\"" << rName << "\")"); 00357 Iterator mit=mNameToFunctionDef.find(rName); 00358 if(mit == End()) { 00359 std::stringstream err; 00360 err << "Unknown function " << rName << std::endl; 00361 throw Exception("FunctionRegistry::NewFunction()", err.str(), 47); 00362 } 00363 Function* res=mit->second->NewFunction(); 00364 if(!res) { 00365 std::stringstream err; 00366 err << "Failed to instatiate new " << rName << std::endl; 00367 throw Exception("FunctionRegistry::NewFunction()", err.str(), 47); 00368 } 00369 return res; 00370 } 00371 00372 // construct faudes object by function reference 00373 Function* FunctionRegistry::NewFunction(const Function& rFunction) const{ 00374 FD_DRTI("FunctionRegistry::NewFunction(prototype): typeid " << typeid(rFunction).name()); 00375 Iterator mit; 00376 mit=mIdToFunctionDef.find(typeid(rFunction).name()); 00377 if(mit == mIdToFunctionDef.end()) { 00378 std::stringstream err; 00379 err << "Unknown function by reference" << std::endl; 00380 throw Exception("FunctionRegistry::NewFunction()", err.str(), 47); 00381 } 00382 return(rFunction.New()); 00383 } 00384 00385 // access function definition by function name 00386 const FunctionDefinition& FunctionRegistry::Definition(const std::string& rName) const{ 00387 FD_DRTI("FunctionRegistry::Definition( " << rName << " )"); 00388 Iterator mit=mNameToFunctionDef.find(rName); 00389 if(mit == End()) { 00390 std::stringstream err; 00391 err << "Function not found: " << rName; 00392 throw Exception("FunctionRegistry::Definition()", err.str(), 46); 00393 } 00394 return(*(mit->second)); 00395 } 00396 00397 // access function definition by functiond reference 00398 // todo: have function id map 00399 const FunctionDefinition& FunctionRegistry::Definition(const Function& rFunction) const{ 00400 FD_DRTI("FunctionRegistry::Definition(): typeid " << typeid(rFunction).name()); 00401 Iterator mit; 00402 mit=mIdToFunctionDef.find(typeid(rFunction).name()); 00403 if(mit!=mIdToFunctionDef.end()) return *(mit->second); 00404 /* 00405 Iterator mit; 00406 for(mit = Begin(); mit != End(); mit++){ 00407 if(typeid(rFunction) == typeid(*(mit->second->Prototype()))) 00408 return *(mit->second); 00409 } 00410 */ 00411 std::stringstream err; 00412 err << "Function not found: " << typeid(rFunction).name(); 00413 throw Exception("FunctionRegistry::Definition()", err.str(), 46); 00414 } 00415 00416 // test existsnce by function name 00417 bool FunctionRegistry::Exists(const std::string& rName) const{ 00418 return mNameToFunctionDef.find(rName) != End(); 00419 } 00420 00421 // test existsnce by function name 00422 bool FunctionRegistry::Exists(const Function& rFunction) const{ 00423 return mIdToFunctionDef.find(typeid(rFunction).name()) != mIdToFunctionDef.end(); 00424 } 00425 00426 00427 // token write (informative/debugging) 00428 void FunctionRegistry::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00429 FD_DRTI("FunctionRegistry::DoWrite(): file " << rTw.FileName()); 00430 // ignore label and context 00431 (void) rLabel; 00432 (void) pContext; 00433 // doit 00434 rTw.WriteBegin("FunctionRegistry"); 00435 Iterator tit; 00436 for(tit=Begin();tit!=End();tit++) { 00437 // write function definition 00438 tit->second->Write(rTw); 00439 } 00440 rTw.WriteEnd("FunctionRegistry"); 00441 } 00442 00443 00444 /* 00445 ******************************************************************** 00446 ******************************************************************** 00447 ******************************************************************** 00448 00449 Implemantation of LoadRegistry 00450 00451 ******************************************************************** 00452 ******************************************************************** 00453 ******************************************************************** 00454 */ 00455 00456 // load from file 00457 void LoadRegistry(const std::string& rPath) { 00458 FD_DRTI("LoadRegistry(" << rPath << ")"); 00459 // default path 00460 std::string rtipath = rPath; 00461 if(rtipath=="") rtipath="../doc/registry/registry.rti"; // todo: plattform/configure 00462 // clear 00463 TypeRegistry::G()->Clear(); 00464 FunctionRegistry::G()->Clear(); 00465 00466 // auto install types with rti file 00467 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00468 LoadAutoregisteredTypes(); 00469 #endif 00470 00471 // install programmatic functions 00472 //FunctionRegistry::G()->Insert<RtiReachability>("Reachability Tests"); 00473 //FunctionRegistry::G()->Insert<RtiIntegerSum>("IntegerSum"); 00474 FunctionRegistry::G()->Insert<TNestedFunction<Integer,IntegerSum> >("IntegerSum"); 00475 FunctionRegistry::G()->Insert<TNestedFunction<vGenerator,LanguageUnion> >("LanguageUnion"); 00476 FunctionRegistry::G()->Insert<TNestedFunction<vGenerator,LanguageIntersection> >("LanguageIntersection"); 00477 00478 // allow build system load registry programmatic contributions defined in plugins 00479 #ifdef FAUDES_PLUGINS_RTILOAD 00480 FAUDES_PLUGINS_RTILOAD; 00481 #endif 00482 00483 // auto install functions 00484 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00485 LoadAutoregisteredFunctions(); 00486 #endif 00487 00488 // merge documentation 00489 TypeRegistry::G()->MergeDocumentation(rtipath); 00490 FunctionRegistry::G()->MergeDocumentation(rtipath); 00491 00492 // test and report status 00493 #ifdef FAUDES_CHECKED 00494 #ifndef FAUDES_MUTE_RTIAUTOLOAD 00495 TypeRegistry::Iterator tit; 00496 for(tit=TypeRegistry::G()->Begin(); tit!=TypeRegistry::G()->End(); tit++) { 00497 // should have prototype 00498 if(tit->second->Prototype()==NULL) 00499 FD_WARN("TypeRegistry: " << tit->second->Name() << " has no prototype"); 00500 } 00501 FunctionRegistry::Iterator fit; 00502 for(fit=FunctionRegistry::G()->Begin(); fit!=FunctionRegistry::G()->End(); fit++) { 00503 // should have prototype 00504 if(fit->second->Prototype()==NULL) 00505 FD_WARN("FunctionRegistry: " << fit->second->Name() << " has no prototype"); 00506 } 00507 #endif 00508 #endif 00509 00510 FD_DRTI("LoadRegistry(" << rPath << "): done"); 00511 } 00512 00513 // clear all 00514 void ClearRegistry(void) { 00515 FD_DRTI("ClearRegistry()"); 00516 // clear 00517 FunctionRegistry::G()->Clear(); 00518 TypeRegistry::G()->Clear(); 00519 } 00520 00521 // conveience access to singleton 00522 Type* NewObject(const std::string& rTypeName) { return TypeRegistry::G()->NewObject(rTypeName);} 00523 const std::string& TypeName(const Type& rObject) { return TypeRegistry::G()->TypeName(rObject);} 00524 Function* NewFunction(const std::string& rFunctName) { return FunctionRegistry::G()->NewFunction(rFunctName);} 00525 00526 00527 } // namespace |
libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6