00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef _MSC_VER
00014 #pragma warning( disable : 4786 ) // 'identifier' : identifier was truncated to 'number' characters in the debug information
00015
00016
00017 #pragma warning( disable : 4251 ) // 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
00018 #endif
00019 #ifdef __INTEL_COMPILER
00020 #pragma warning( disable : 985 ) // == C4786
00021 #endif
00022
00023 #include "FSM.h"
00024 #include "FiniteStateMachine-config.h"
00025 #include "FSMErrorCodes.h"
00026
00027 namespace FSM {
00028
00029
00030 static const char* FSM_CONDITION_EQUAL = "==";
00031 static const char* FSM_CONDITION_NEQUAL = "!=";
00032 static const char* FSM_CONDITION_GREATER = ">";
00033 static const char* FSM_CONDITION_LESS = "<";
00034 static const char* FSM_CONDITION_GREATER_EQ = ">=";
00035 static const char* FSM_CONDITION_LESS_EQ = "<=";
00036
00037 static const char* FSM_PARAM_VARIABLE = "Variable";
00038 static const char* FSM_PARAM_CONDITION = "Condition";
00039 static const char* FSM_PARAM_VALUE = "Value";
00040 static const char* FSM_PARAM_EXPRESSION = "Expression";
00041
00042
00044
00046
00047 {
00048 return true;
00049 }
00050
00051 bool CFSMCondition::Deactivate()
00052 {
00053 return true;
00054 }
00055
00057
00059
00060 {
00061 }
00062
00063 CFSMCondition::~CFSMCondition()
00064 {
00065 }
00066
00068
00070
00072
00074
00075 {
00076 variableName = varName;
00077 condition=testCondition;
00078 value=testValue;
00079 }
00080
00081 const char* CFSMConditionTestVariable::GetVariable() const
00082 {
00083 return variableName.c_str();
00084 }
00085
00086 CFSMConditionTestVariable::OP CFSMConditionTestVariable::GetCondition() const
00087 {
00088 return condition;
00089 }
00090
00091 int CFSMConditionTestVariable::GetValue() const
00092 {
00093 return value;
00094 }
00095
00096 bool CFSMConditionTestVariable::SetExpression(const char* expression)
00097 {
00098 char var[1024];
00099 char cond[20];
00100 char value[50];
00101 const char *p = expression;
00102 bool res = false;
00103
00104 char *dest = var;
00105 while (dest)
00106 {
00107 switch(*p)
00108 {
00109 case '=':
00110 case '>':
00111 case '<':
00112 case '!':
00113 case ' ':
00114 case '\t':
00115 case '\n':
00116 case '\0':
00117 *dest='\0';
00118 dest = NULL;
00119 break;
00120 default:
00121 *dest = *p;
00122 ++dest;
00123 ++p;
00124 break;
00125 }
00126 }
00127
00128 dest = cond;
00129 while (dest)
00130 {
00131 switch(*p)
00132 {
00133 case '=':
00134 case '>':
00135 case '<':
00136 case '!':
00137 *dest = *p;
00138 ++dest;
00139 ++p;
00140 break;
00141 case ' ':
00142 case '\t':
00143 case '\n':
00144 case '\0':
00145 ++p;
00146 break;
00147 default:
00148 *dest='\0';
00149 dest = NULL;
00150 break;
00151 }
00152 }
00153
00154 dest = value;
00155 while (dest)
00156 {
00157 switch(*p)
00158 {
00159 case '\0':
00160 case ' ':
00161 case '\t':
00162 case '\n':
00163 *dest='\0';
00164 dest = NULL;
00165 break;
00166 default:
00167 *dest = *p;
00168 ++dest;
00169 ++p;
00170 break;
00171 }
00172 }
00173
00174 if (SetParameter(FSM_PARAM_VARIABLE, var))
00175 {
00176 if (SetParameter(FSM_PARAM_CONDITION, cond))
00177 {
00178 if (SetParameter(FSM_PARAM_VALUE, value))
00179 {
00180 res = true;
00181 }
00182 }
00183 }
00184 return res;
00185 }
00186
00188
00190
00191 bool CFSMConditionTestVariable::SetParameter(const char *paramName, const char* paramValue)
00192 {
00193 bool res = false;
00194 if(strncmp(paramName, FSM_PARAM_VALUE, strlen(FSM_PARAM_VALUE))==0)
00195 {
00196 value = atoi(paramValue);
00197 res = true;
00198 } else
00199
00200 if(strncmp(paramName, FSM_PARAM_VARIABLE, strlen(FSM_PARAM_VARIABLE))==0)
00201 {
00202 variableName = paramValue;
00203 res = true;
00204 } else
00205
00206 if(strncmp(paramName, FSM_PARAM_CONDITION, strlen(FSM_PARAM_CONDITION))==0)
00207 {
00208 if(strncmp(paramValue, FSM_CONDITION_EQUAL, strlen(FSM_CONDITION_EQUAL))==0)
00209 {
00210 condition = EQUAL;
00211 res = true;
00212 } else
00213
00214 if(strncmp(paramValue, FSM_CONDITION_NEQUAL, strlen(FSM_CONDITION_NEQUAL))==0)
00215 {
00216 condition = NEQUAL;
00217 res = true;
00218 } else
00219
00220 if(strncmp(paramValue, FSM_CONDITION_GREATER_EQ, strlen(FSM_CONDITION_GREATER_EQ))==0)
00221 {
00222 condition = GREATER_EQ;
00223 res = true;
00224 } else
00225
00226 if(strncmp(paramValue, FSM_CONDITION_LESS_EQ, strlen(FSM_CONDITION_LESS_EQ))==0)
00227 {
00228 condition = LESS_EQ;
00229 res = true;
00230 } else
00231
00232 if(strncmp(paramValue, FSM_CONDITION_GREATER, strlen(FSM_CONDITION_GREATER))==0)
00233 {
00234 condition = GREATER;
00235 res = true;
00236 } else
00237
00238 if(strncmp(paramValue, FSM_CONDITION_LESS, strlen(FSM_CONDITION_LESS))==0)
00239 {
00240 condition = LESS;
00241 res = true;
00242 } else
00243
00244 {
00245 iThrow(CRITICAL(FSM_UNKNOWN_CONDITION_VALUE), paramValue, paramName, GetNameOfClass());
00246 }
00247 } else
00248
00249 if(strcmp(paramName, FSM_PARAM_EXPRESSION)==0)
00250 {
00251 res = SetExpression(paramValue);
00252 } else
00253
00254
00255 {
00256 iThrow(CRITICAL(FSM_UNKNOWN_PARAM), paramName, GetNameOfClass());
00257 }
00258
00259 return res;
00260 }
00261
00262 bool CFSMConditionTestVariable::CheckCondition(const char* event, void *a, void *b)
00263 {
00264 bool res = false;
00265 int varValue=0;
00266
00267 if(variableName.empty())
00268 {
00269 iThrow(WARNING(FSM_PARAM_NOT_SET), GetNameOfClass());
00270 return false;
00271 }
00272
00273 if( !GetFSM()->GetVariable(variableName.c_str(), varValue) )
00274 {
00275 iHandleLastError();
00276 return false;
00277 }
00278
00279 switch(condition)
00280 {
00281 case EQUAL:
00282 res = (varValue==value);
00283 break;
00284 case NEQUAL:
00285 res = (varValue!=value);
00286 break;
00287 case GREATER:
00288 res = (varValue>value);
00289 break;
00290 case LESS:
00291 res = (varValue<value);
00292 break;
00293 case GREATER_EQ:
00294 res = (varValue>=value);
00295 break;
00296 case LESS_EQ:
00297 res = (varValue<=value);
00298 break;
00299 }
00300 return res;
00301 }
00302
00304
00306
00307 {
00308 return new CFSMConditionTestVariable;
00309 }
00310
00311 void CFSMConditionTestVariable::DeleteThis()
00312 {
00313 delete this;
00314 }
00315
00317
00319
00320 {
00321 const char* cond=NULL;
00322 if (!out->SaveParameter(FSM_PARAM_VARIABLE, variableName.c_str())) {iRethrow(); return false;}
00323 switch(condition)
00324 {
00325 case EQUAL:
00326 cond=FSM_CONDITION_EQUAL;
00327 break;
00328 case NEQUAL:
00329 cond=FSM_CONDITION_NEQUAL;
00330 break;
00331 case GREATER:
00332 cond=FSM_CONDITION_GREATER;
00333 break;
00334 case LESS:
00335 cond=FSM_CONDITION_LESS;
00336 break;
00337 case GREATER_EQ:
00338 cond=FSM_CONDITION_GREATER_EQ;
00339 break;
00340 case LESS_EQ:
00341 cond=FSM_CONDITION_LESS_EQ;
00342 break;
00343 default:
00344 iThrow(CRITICAL(FSM_UNKNOWN_CONDITION), condition);
00345 return false;
00346 break;
00347 }
00348 if (!out->SaveParameter(FSM_PARAM_CONDITION, cond)) {iRethrow(); return false;}
00349 char buf[20];
00350 sprintf(buf, "%d", value);
00351 if (!out->SaveParameter(FSM_PARAM_VALUE, buf)) {iRethrow(); return false;}
00352 return true;
00353 }
00354
00356
00358
00359 {
00360 }
00361
00362 CFSMConditionTestVariable::~CFSMConditionTestVariable()
00363 {
00364 }
00365
00367 };
00368