Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / ai_data_service / primitive_crunch.cpp
blobc08be9c5871e67e62253bc327681c77cc6e4c089
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //===================================================================
22 #include "nel/misc/debug.h"
24 #include "game_share/xml.h"
26 #include "ai_manager.h"
27 #include "ai_service.h"
28 #include "ai_files.h"
30 //===================================================================
32 //---------------------------------------------------
33 // INSTANTIATED CLASS: Public methods
35 //-------------
36 // a few read accessors (static properties)
38 // the manager id (0..255)
39 sint CAIManager::id() const
41 return int(this-_managers);
43 // the manager name .. ie the source file name minus extension
44 const std::string &CAIManager::name() const
46 return _name;
49 // the CPU load rating of the manager for auto-load ballancing purposes
50 uint CAIManager::weightCPU() const
52 return _weightCPU;
54 // the RAM load rating of the manager for auto-load ballancing purposes
55 uint CAIManager::weightRAM() const
57 return _weightRAM;
61 //-------------
62 // a few read accessors (state of the files on disk)
64 // indicates whether newer source files than object files have been located
65 bool CAIManager::needCompile() const
67 return _needCompile;
69 // indicate whether an object file has been located in the object directory
70 bool CAIManager::objExists() const
72 return _objExists;
76 //-------------
77 // a few read accessors (relating to assignment to & execution by an ai service)
79 // has the manager been opened (it may still be waiting to be assigned)
80 bool CAIManager::isOpen() const
82 return _isOpen;
84 // has the manager been assigned to a service
85 bool CAIManager::isAssigned() const
87 return _isAssigned;
89 // is the manager up and running on the assigned service
90 bool CAIManager::isUp() const
92 return _isUp;
95 // the id of the service to which the manager is assigned
96 sint CAIManager::serviceId() const
98 return _service;
102 //-------------
103 // a few basic actions (relating to disk files)
105 const std::string &xmlDelimitedString(CxmlNode *xmlNode,const std::string &delimiter)
107 static const std::string emptyString;
109 for (uint i=0;i<xmlNode->childCount();++i)
111 CxmlNode *child=xmlNode->child(i);
112 if (child->type()==delimiter)
113 if (child->childCount()==1)
114 if (child->child(0)->type()=="")
116 return child->child(0)->txt();
120 return emptyString;
123 const std::string &getProp(CxmlNode *xmlNode,const std::string &propertyName)
125 static const std::string emptyString;
127 for (uint i=0;i<xmlNode->childCount();++i)
129 CxmlNode *child=xmlNode->child(i);
130 if (child->type()=="PROPERTY")
132 const std::string &name= xmlDelimitedString(child,std::string("NAME"));
133 if (name==propertyName)
134 return xmlDelimitedString(child,std::string("STRING"));
137 return emptyString;
140 // compile the source files to generate new object files
141 void CAIManager::compile()
143 std::string srcFile=CAIFiles::fullSrcFileName(id());
144 std::string objFile=CAIFiles::fullObjFileName(id());
145 nlinfo("Compile %s => %s",srcFile.c_str(),objFile.c_str());
147 // open and parse the xml file
148 CxmlNode xmlfile;
149 xmlfile.read(srcFile);
151 // locate the mgr node in the file
152 std::list <CxmlNode *> nodes;
153 nodes.push_back(&xmlfile);
154 while (!nodes.empty())
156 // pop the next node off the list
157 CxmlNode *node=*nodes.begin();
158 nodes.pop_front();
160 // push our children so that they can be treated too
161 for (uint i=0;i<node->childCount();++i)
162 nodes.push_back(node->child(i));
164 // if this is a child node then we're in business so dump a few infos to the screen
165 if (node->type()=="CHILD" && !getProp(node,std::string("AI_TYPE")).empty())
167 nlinfo("child: AI_TYPE: %s NAME: %s",getProp(node,std::string("AI_TYPE")).c_str(),getProp(node,std::string("Name")).c_str());
172 // delete the object files (but not the save files)
173 void CAIManager::clean()
175 CAIFiles::clean(id());
179 //-------------
180 // a few basic actions (relating to assignment to & execution by an ai service)
182 // open the manager on an unspecified service
183 // (may be queued until a service is available)
184 void CAIManager::open()
186 CAIService::openMgr(id());
189 // assign manager to a specified service and begin execution
190 void CAIManager::assign(sint serviceId)
192 // make sure that the manager isn't assigned to a service already
193 if (isAssigned())
195 nlwarning("Cannot assign manager %04d (%s) to service %d as already assigned to %d",
196 id(), name(), serviceId, _service);
197 return;
200 // flag me as assigned
201 _isAssigned=true;
202 _service=serviceId;
204 // transfer control to the service's assignMgr() method
205 CAIService *service=CAIService::getServiceById(serviceId);
206 if (service!=NULL)
207 service->assignMgr(id());
210 // stop execution on the current service and assign to a new service
211 void CAIManager::reassign(sint serviceId)
213 CAIService *service=CAIService::getServiceById(_service);
214 if (service!=NULL)
215 service->reassignMgr(id(),serviceId);
218 // stop execution of a manager
219 void CAIManager::close()
221 // make sure that the manager isn't assigned to a service already
222 if (!isAssigned())
224 nlwarning("Cannot unassign manager %04d (%s) as it is already unassigned", id(), name());
225 return;
228 // if the service is running then transfer control to the service singleton's closeMgr() method
229 if (isUp())
231 CAIService::closeMgr(id());
232 return;
235 // flag me as unassigned
236 _isAssigned=false;
237 _isOpen=false;
238 _service=-1;
242 //-------------
243 // a few basic actions (miscelaneous)
245 // display information about the state of the manager
246 void CAIManager::display() const
248 if (isAssigned())
249 nlinfo("AI Manager %04d: %s: %s ON SERVICE %d (%s)", id(), _name.c_str(),
250 isUp()? "UP AND RUNNING":
251 /* else */ "ASSIGNED TO BUT NOT YET UP",
252 _service,
253 isOpen()? "auto-assigned":
254 /* else */ "manualy assigned"
256 else
257 nlinfo("AI Manager %04d: %s: %s", id(), _name.c_str(),
258 isOpen()? "OPEN - AWAITING ASSIGNMENT":
259 !objExists()? "NOT OPEN - OBJECT FILE NOT FOUND":
260 needCompile()? "NOT OPEN - OBJECT FILE OLDER THAN SOURCE":
261 /* else */ "NOT OPEN - OBJECT FILE IS UP TO DATE"
266 //-------------
267 // a few write accessors (miscelaneous)
269 // set the name assigned to manager
270 // if no name previously assigned then reset all manager properties
271 // if a name already exists and does not match new name then do nohing and return false
272 bool CAIManager::set(const std::string &name)
274 // if we already have a name associated with this slot then simply check that it matches the new name
275 if (!_name.empty())
276 return (_name==name);
277 _reset();
278 _name=name;
279 return true;
282 // set the state of the needCompile flag
283 void CAIManager::setNeedCompile(bool val)
285 _needCompile=val;
288 // set the state of the objFileExists flag
289 void CAIManager::setObjFileExists(bool val)
291 _objExists=val;
294 // set the state of the isUp flag
295 void CAIManager::setIsUp(bool val)
297 _isUp=val;
300 // set the state of the isOpen flag
301 void CAIManager::setIsOpen(bool val)
303 _isOpen=val;
307 //---------------------------------------------------
308 // INSTANTIATED CLASS: Private methods
310 // default constructor - may only be instantiated by the singleton
311 CAIManager::CAIManager()
313 // manager id - make sure that the managers are all in the one static array
314 // note that id is calaulated from the array address and the addess of 'this'
315 nlassert(uint(id())<maxManagers());
316 // reset the rest of the properties
317 _reset();
320 void CAIManager::_reset()
322 _name.clear();
323 _weightCPU = 0;
324 _weightRAM = 0;
325 _needCompile = false;
326 _objExists = false;
327 _isOpen = false;
328 _isAssigned = false;
329 _isUp = false;
330 _service = -1;
334 //===================================================================
335 // *** END OF THE INSTANTIATED CLASS *** START OF THE SINGLETON ***
336 //===================================================================
339 //---------------------------------------------------
340 // SINGLETON: Data
342 class CAIManager CAIManager::_managers[RYAI_AI_MANAGER_MAX_MANAGERS];
345 //---------------------------------------------------
346 // SINGLETON: Public methods
348 // get the number of allocated managers
349 uint CAIManager::numManagers()
351 uint count=0;
352 for (uint i=0;i<maxManagers();i++)
353 if (!_managers[i]._name.empty())
354 count++;
355 return count;
358 // get a pointer to the manager with given handle (0..maxManagers-1)
359 CAIManager *CAIManager::getManagerById(sint id)
361 if (uint(id)>=maxManagers())
363 nlwarning("CAIManager::getManagerById(id): id %d not in range 0..%d",id,maxManagers()-1);
364 return NULL;
366 return &(_managers[id]);
369 // get a pointer to the manager with given index (0..numManagers-1)
370 CAIManager *CAIManager::getManagerByIdx(uint idx)
372 uint count=0;
373 for (uint i=0;i<maxManagers();i++)
374 if (!_managers[i]._name.empty())
376 if (idx==count)
377 return &(_managers[i]);
378 count++;
380 nlwarning("CAIManager::getManagerByIdx(idx): idx (%d)>=numManagers (%d)",idx,count);
381 return NULL;
384 // get the handle for the manager of given name and optionally create a new
385 // handle if none found - return -1 if none found or no free slots
386 int CAIManager::nameToId(std::string name, bool assignNewIfNotFound)
388 // see if the name is a numeric version of an id
389 uint val=atoi(name.c_str());
390 if (!name.empty() && name.size()<=4 &&
391 ( (val>0 && val<maxManagers()) ||
392 (val==0 && name==std::string("0000"+4-name.size())) ) )
393 return val;
395 // see if the name is already assigned to one of the _managers
396 for (uint i=0;i<maxManagers();i++)
397 if (_managers[i]._name==name)
398 return i;
400 // the name's not been found so if assignNewIfNotFound then look for a free slot
401 if (assignNewIfNotFound)
403 for (uint i=0;i<maxManagers();i++)
404 if (_managers[i]._name.empty())
406 _managers[i].set(name);
407 return i;
409 nlwarning("Failed to allocate a manager for name '%s' (all %d managers are already allocated)",name.c_str(),maxManagers());
411 return -1;
414 // clear file name assignments for managers that aren't currently running on
415 // ai services
416 void CAIManager::liberateUnassignedManagers()
418 for (uint i=0;i<maxManagers();i++)
419 if (!_managers[i]._isOpen && !_managers[i]._isAssigned)
420 _managers[i]._reset();
424 //===================================================================