/** @file /ai/aiscriptcaller.cpp @brief Implementace tridy pro volani AI skriptu. @author PZ @version 0.1 */ #include "ai/aiscriptcaller.h" namespace ai_ns { CTCLAIVar::CTCLAIVar() { } CTCLAIVar::~CTCLAIVar() { clearAll(); } void CTCLAIVar::clearAll() { std::AI_SCRIPT_VARIABLES_CONTAINER::iterator it; for(it=varcontainer.begin();it!=varcontainer.end();it++) { KMemFree(it->name); KMemFree(it->data); } varcontainer.clear(); } void CTCLAIVar::addInt(char* varName,int value) { int nlen=(int) strlen(varName); TTCLAIVariableDescription aInt; aInt.varType=AVT_INT; aInt.name=(char*) KMemAlloc((nlen+1)*sizeof(char)); memcpy(aInt.name,varName,nlen); (aInt.name)[nlen]='\0'; int* tmp; tmp=(int*) KMemAlloc(sizeof(int)); *tmp=value; aInt.data=tmp; varcontainer.push_back(aInt); } void CTCLAIVar::addReal(char* varName,float value) { int nlen=(int) strlen(varName); TTCLAIVariableDescription aReal; aReal.varType=AVT_REAL; aReal.name=(char*) KMemAlloc((nlen+1)*sizeof(char)); memcpy(aReal.name,varName,nlen); (aReal.name)[nlen]='\0'; float* tmp; tmp=(float*) KMemAlloc(sizeof(float)); *tmp=value; aReal.data=tmp; varcontainer.push_back(aReal); } void CTCLAIVar::addString(char* varName,char* value) { int nlen=(int) strlen(varName); TTCLAIVariableDescription aString; aString.varType=AVT_STRING; aString.name=(char*) KMemAlloc((nlen+1)*sizeof(char)); memcpy(aString.name,varName,nlen); (aString.name)[nlen]='\0'; char* tmp; int vlen=(int) strlen(value); tmp=(char*) KMemAlloc((vlen+1)*sizeof(char)); memcpy(tmp,value,vlen); tmp[vlen]='\0'; aString.data=tmp; varcontainer.push_back(aString); } int CTCLAIVar::getInt(char* varName) throw(E_8K_AI_VarNotFound,E_8K_AI_BadVarType) { std::AI_SCRIPT_VARIABLES_CONTAINER::iterator it; for(it=varcontainer.begin();it!=varcontainer.end();it++) { if (strcmp(it->name,varName)==0) { if (it->varType!=AVT_INT) THROW(E_8K_AI_BadVarType,"Nalezena promenna ma chybny typ."); return (*((int*) (it->data))); } } THROW(E_8K_AI_VarNotFound,"Promenna zadaneho jmena nenalezena."); } float CTCLAIVar::getReal(char* varName) throw(E_8K_AI_VarNotFound,E_8K_AI_BadVarType) { std::AI_SCRIPT_VARIABLES_CONTAINER::iterator it; for(it=varcontainer.begin();it!=varcontainer.end();it++) { if (strcmp(it->name,varName)==0) { if (it->varType!=AVT_REAL) THROW(E_8K_AI_BadVarType,"Nalezena promenna ma chybny typ."); return (*((float*) (it->data))); } } THROW(E_8K_AI_VarNotFound,"Promenna zadaneho jmena nenalezena."); } char* CTCLAIVar::getString(char* varName) throw(E_8K_AI_VarNotFound,E_8K_AI_BadVarType) { std::AI_SCRIPT_VARIABLES_CONTAINER::iterator it; for(it=varcontainer.begin();it!=varcontainer.end();it++) { if (strcmp(it->name,varName)==0) { if (it->varType!=AVT_STRING) THROW(E_8K_AI_BadVarType,"Nalezena promenna ma chybny typ."); return ((char*) (it->data)); } } THROW(E_8K_AI_VarNotFound,"Promenna zadaneho jmena nenalezena."); } CAIScriptCaller::CAIScriptCaller() { rmxi=(rm::TRM_xml_i*) KSendGlobalMessage(MSG_GET_RM_XML_I,0,0,(void*) STRUCT_TCL); } CAIScriptCaller::~CAIScriptCaller() { delete rmxi; } CTCLAIVar* CAIScriptCaller::countScript(int scriptID,CTCLAIVar* scriptInput) throw(E_8K_AI_BadScriptCounting) { CTCLAIVar* rv=0; TCLinter=new TTCL_Interpreter(); TTCL_Script* scr_worker=new TTCL_Script(TCLinter); TCL_SCRIPT* scr; rmxi->request(scriptID); rmxi->loadBuffer(); rmxi->get(&scr,scriptID); scr_worker->loadStruct(scr); try { int ic; for(ic=0;icinput_size;ic++) { switch ((scr->input[ic]).type) { case TVT_INT:{ int tmpint=scriptInput->getInt((scr->input[ic]).name); scr_worker->setVar((scr->input[ic]).name,&tmpint); } break; case TVT_FLOAT:{ float tmpfloat=scriptInput->getReal((scr->input[ic]).name); scr_worker->setVar((scr->input[ic]).name,&tmpfloat); } break; case TVT_STRING:scr_worker->setVar((scr->input[ic]).name,scriptInput->getString((scr->input[ic]).name)); break; default:THROW(E_8K_AI_BadScriptCounting,"Chybny typ vstupni promenne."); } } } catch (E_8K_AI_VarNotFound e) { THROW(E_8K_AI_BadScriptCounting,e.getDescription()); } catch (E_8K_AI_BadVarType e) { THROW(E_8K_AI_BadScriptCounting,e.getDescription()); } if (scr_worker->run()==TCL_OK) { rv=new CTCLAIVar(); int ic; for(ic=0;icoutput_size;ic++) { switch ((scr->output[ic]).type) { case TVT_INT:{ int tmpint; if (!(scr_worker->getVar((scr->output[ic]).name,&tmpint))) { THROW(E_8K_AI_BadScriptCounting,"Spatny vypocet TCL skriptu.") } else { rv->addInt((scr->output[ic]).name,tmpint); } } break; case TVT_FLOAT:{ float tmpfloat; if (!(scr_worker->getVar((scr->output[ic]).name,&tmpfloat))) { THROW(E_8K_AI_BadScriptCounting,"Spatny vypocet TCL skriptu.") } else { rv->addReal((scr->output[ic]).name,tmpfloat); } } break; case TVT_STRING:{ char tmpstring[STRING_VARIABLE_BUFFER_SIZE]; if (!(scr_worker->getVar((scr->output[ic]).name,tmpstring))) { THROW(E_8K_AI_BadScriptCounting,"Spatny vypocet TCL skriptu.") } else { tmpstring[STRING_VARIABLE_BUFFER_SIZE-1]='\0'; rv->addString((scr->output[ic]).name,tmpstring); } } break; default:THROW(E_8K_AI_BadScriptCounting,"Chybny typ vystupni promenne."); } } } delete scr_worker; delete TCLinter; return rv; } }