2 //-----------------------------------------------------------------------------
4 //-----------------------------------------------------------------------------
9 #include "game_share/utils.h"
10 #include "game_share/persistent_data.h"
14 #include "ai_actions.h"
16 #include "ai_actions_dr.h"
19 //-------------------------------------------------------------------------------------------------
21 //-------------------------------------------------------------------------------------------------
24 using namespace NLMISC
;
25 using namespace NLNET
;
26 using namespace AI_SHARE
;
28 //---------------------------------------------------------------------------------------
29 // Stuff used for management of log messages
31 static bool VerboseLog
=false;
32 #define LOG if (!VerboseLog) {} else NLMISC::InfoLog->displayNL
35 //-------------------------------------------------------------------------------------------------
37 //-------------------------------------------------------------------------------------------------
40 extern NLLIGO::CLigoConfig LigoConfig
;
44 //-------------------------------------------------------------------------------------------------
45 // methods CAIActionsDataRecordPtr
46 //-------------------------------------------------------------------------------------------------
48 void CAIActionsDataRecordPtr::clear()
53 void CAIActionsDataRecordPtr::readFile(const std::string
&fileName
)
55 _PdrPtr
->readFromFile(fileName
);
58 void CAIActionsDataRecordPtr::writeFile(const std::string
&fileName
)
60 _PdrPtr
->writeToFile(fileName
);
63 void CAIActionsDataRecordPtr::display()
69 for (uint32 i
=0;i
<lines
.size();++i
)
71 LOG("AIActions: %s",lines
[i
].c_str());
75 void CAIActionsDataRecordPtr::serial(NLMISC::IStream
&stream
)
77 if (!stream
.isReading())
79 // calculate and write the data block size
80 uint32 buffSize
= _PdrPtr
->totalDataSize();
81 stream
.serial(buffSize
);
83 // allocate a buffer to store the data block temporarily and dump data into it
84 char* buffer
= (char*)malloc(buffSize
);
85 nlassert(buffer
!=NULL
);
86 _PdrPtr
->toBuffer(buffer
,buffSize
);
88 // write the buffer to the stream
89 stream
.serialBuffer((uint8
*)buffer
,buffSize
);
93 // read the buffer size from the stream
95 stream
.serial(buffSize
);
97 // allocate a temporary memory buffer and copy out the serialised data block
98 char* buffer
= (char*)malloc(buffSize
);
99 nlassert(buffer
!=NULL
);
100 stream
.serialBuffer((uint8
*)buffer
,buffSize
);
102 // decode the buffer contents to PDR representation
103 _PdrPtr
->fromBuffer(buffer
,buffSize
);
107 void CAIActionsDataRecordPtr::addOpenFile(const std::string
&fileName
)
109 LOG("AIActions: openFile(\"%s\")",fileName
.c_str());
111 _PdrPtr
->push(_PdrPtr
->addString("fileName"),fileName
);
112 _PdrPtr
->pushStructBegin(_PdrPtr
->addString("file"));
115 void CAIActionsDataRecordPtr::addCloseFile(const std::string
&fileName
)
117 LOG("AIActions: closeFile(\"%s\")",fileName
.c_str());
119 _PdrPtr
->pushStructEnd(_PdrPtr
->addString("file"));
122 void CAIActionsDataRecordPtr::addExecute(uint64 action
,const std::vector
<CAIActions::CArg
> &args
)
124 // convert the 64 bit action ID to a text string
127 *(uint64
*)&actionName
[0]=action
;
129 LOG("AIActions: execute(\"%s\" with %d args)",actionName
,args
.size());
131 // push any arguments belonging to the action
132 for (uint32 i
=0;i
<args
.size();++i
)
134 args
[i
].pushToPdr(*_PdrPtr
);
137 // push the action itself
138 _PdrPtr
->push(_PdrPtr
->addString(actionName
));
141 void CAIActionsDataRecordPtr::addBegin(uint32 contextAlias
)
143 LOG("AIActions: begin(%i)",contextAlias
);
145 _PdrPtr
->push(_PdrPtr
->addString("contextAlias"),contextAlias
);
146 _PdrPtr
->pushStructBegin(_PdrPtr
->addString("context"));
149 void CAIActionsDataRecordPtr::addEnd(uint32 contextAlias
)
151 LOG("AIActions: end(%i)",contextAlias
);
153 _PdrPtr
->pushStructEnd(_PdrPtr
->addString("context"));
156 static uint64
stringToInt64(const char *str
)
160 for (i
=0;i
<8 && str
[i
]!=0;++i
)
161 ((char *)&id
)[i
]=str
[i
];
163 // the following assert ensures that we never try to cram >8 letters into an int64
169 void CAIActionsDataRecordPtr::applyToExecutor(CAIActions::IExecutor
& executor
)
171 std::vector
<CAIActions::CArg
> args
;
172 std::vector
<uint32
> contextStack
;
173 std::string fileName
;
174 uint32 contextAlias
=~0u;
177 while (!_PdrPtr
->isEndOfData())
180 CPersistentDataRecord::TToken token
= _PdrPtr
->peekNextToken();
182 const std::string
& tokenName
= _PdrPtr
->peekNextTokenName();
184 if (_PdrPtr
->isStartOfStruct())
186 if (tokenName
=="file")
188 BOMB_IF(!args
.empty(),"Found args with unmatched action in pdr",return);
189 BOMB_IF(contextAlias
!=~0u,"Found context alias without matching context clause",return);
191 executor
.openFile(fileName
);
193 _PdrPtr
->popStructBegin(token
);
197 if (tokenName
=="context")
199 BOMB_IF(!args
.empty(),"Found args with unmatched action in pdr",return);
200 // BOMB_IF(!fileName.empty(),"Found file name without matching file clause",return);
202 executor
.begin(contextAlias
);
203 contextStack
.push_back(contextAlias
);
205 _PdrPtr
->popStructBegin(token
);
209 // if it's not a special case then it must be an argument
210 //BOMB_IF(!fileName.empty(),"Found file name without matching file clause",return);
211 BOMB_IF(contextAlias
!=~0u,"Found context alias without matching context clause",return);
212 vectAppend(args
).popFromPdr(*_PdrPtr
);
216 //BOMB_IF(!fileName.empty(),"Found file name without matching file clause",return);
217 BOMB_IF(contextAlias
!=~0u,"Found context alias without matching context clause",return);
219 if (_PdrPtr
->isEndOfStruct())
221 BOMB_IF(!args
.empty(),"Found args with unmatched action in pdr",return);
223 if (tokenName
=="file")
225 BOMB_IF(fileName
.empty(),"PDR file invalid: found end of file marker but no file open",return);
226 executor
.closeFile(fileName
);
228 _PdrPtr
->popStructEnd(token
);
232 if (tokenName
=="context")
234 BOMB_IF(contextStack
.empty(),"PDR file invalid: found more section closes than opens",return);
235 executor
.end(contextStack
.back());
236 contextStack
.pop_back();
237 _PdrPtr
->popStructEnd(token
);
241 BOMB("I'm not sure we shold be here .... :( bug ???",return);
244 if (_PdrPtr
->isTokenWithNoData())
246 BOMB_IF(tokenName
.size()>8,"The action name '"+tokenName
+"' is invalid - it must be <= 8 characters long",return);
247 executor
.execute(stringToInt64(tokenName
.c_str()),args
);
253 if (tokenName
=="contextAlias")
255 BOMB_IF(!args
.empty(),"Found args with unmatched action in pdr",return);
257 contextAlias
= (uint32
)_PdrPtr
->popNextArg(token
).asUint();
261 if (tokenName
=="fileName")
263 BOMB_IF(!fileName
.empty(),"Found a file clause within another file clause!",return);
264 BOMB_IF(!args
.empty(),"Found args with unmatched action in pdr",return);
266 fileName
= _PdrPtr
->popNextArg(token
).asString();
269 // contxt wiht no value
270 if (tokenName
== "context")
272 BOMB_IF(contextAlias
==~0u,"error",return);
273 executor
.begin(contextAlias
);
274 executor
.end(contextAlias
);
280 // if it's not a special case then it must be an argument
281 vectAppend(args
).popFromPdr(*_PdrPtr
);
285 //---------------------------------------------------------------------------------------
286 // Control over verbose nature of logging
287 //---------------------------------------------------------------------------------------
289 NLMISC_COMMAND(verboseActionsParseLog
,"Turn on or off or check the state of verbose parser activity logging","")
296 if(args
[0]==string("on")||args
[0]==string("ON")||args
[0]==string("true")||args
[0]==string("TRUE")||args
[0]==string("1"))
299 if(args
[0]==string("off")||args
[0]==string("OFF")||args
[0]==string("false")||args
[0]==string("FALSE")||args
[0]==string("0"))
303 nlinfo("verboseLogging is %s",VerboseLog
?"ON":"OFF");
307 //---------------------------------------------------------------------------------------