cyphesis/server/EntityBuilder.cpp

966 lines
35 KiB
C++
Raw Normal View History

2006-01-19 Al Riddoch <alriddoch@zepler.org> * aiclient/ClientAccount.cpp, aiclient/ClientAccount.h, aiclient/ClientConnection.cpp, aiclient/ClientConnection.h, aiclient/client.cpp, aiclient/client.h, client/BaseClient.cpp, client/BaseClient.h, client/CharacterClient.cpp, client/CharacterClient.h, client/ClientConnection.cpp, client/ClientConnection.h, client/CreatorClient.cpp, client/CreatorClient.h, client/ObserverClient.cpp, client/ObserverClient.h, client/Py_CreatorClient.cpp, client/Py_CreatorClient.h, client/client.cpp, client/define_world.cpp, client/define_world.h, common/Add.h, common/Affect.h, common/AtlasFileLoader.cpp, common/AtlasFileLoader.h, common/Attack.h, common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.cpp, common/BaseWorld.h, common/Burn.h, common/Chop.h, common/Connect.h, common/CustomOp.cpp, common/CustomOp.h, common/CustomOp_impl.h, common/Cut.h, common/Database.cpp, common/Database.h, common/Delve.h, common/Dig.h, common/Eat.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/Generic.h, common/Load.h, common/Monitor.h, common/Mow.h, common/Nourish.h, common/OOGThing.cpp, common/OOGThing.h, common/Property.cpp, common/Property.h, common/Property_impl.h, common/Save.h, common/Setup.h, common/Tick.h, common/Unseen.h, common/Update.h, common/Use.h, common/Wield.h, common/accountbase.cpp, common/accountbase.h, common/const.cpp, common/const.h, common/custom.cpp, common/debug.h, common/globals.cpp, common/globals.h, common/id.cpp, common/id.h, common/inheritance.cpp, common/inheritance.h, common/inheritance_impl.h, common/log.cpp, common/log.h, common/newid.cpp, common/nls.h, common/op_switch.h, common/operations.cpp, common/operations.h, common/random.h, common/refno.h, common/serialno.cpp, common/serialno.h, common/system.cpp, common/system.h, common/terrain_utils.cpp, common/terrain_utils.h, common/type_utils.h, common/types.h, common/utility.cpp, common/utility.h, modules/DateTime.cpp, modules/DateTime.h, modules/Location.cpp, modules/Location.h, modules/WorldTime.cpp, modules/WorldTime.h, physics/BBox.cpp, physics/BBox.h, physics/Collision.cpp, physics/Collision.h, physics/Quaternion.cpp, physics/Quaternion.h, physics/Vector3D.cpp, physics/Vector3D.h, physics/VectorPol.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/AreaProperty.cpp, rulesets/AreaProperty.h, rulesets/ArithmeticScript.cpp, rulesets/ArithmeticScript.h, rulesets/BaseMind.cpp, rulesets/BaseMind.h, rulesets/CalendarProperty.cpp, rulesets/CalendarProperty.h, rulesets/Character.cpp, rulesets/Character.h, rulesets/Combat.cpp, rulesets/Combat.h, rulesets/Container.cpp, rulesets/Container.h, rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityProperties.cpp, rulesets/Entity_getLocation.h, rulesets/Fell.cpp, rulesets/Fell.h, rulesets/Food.cpp, rulesets/Food.h, rulesets/Line.cpp, rulesets/Line.h, rulesets/LineProperty.cpp, rulesets/LineProperty.h, rulesets/MemEntity.cpp, rulesets/MemEntity.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/MemMap_methods.h, rulesets/MindFactory.cpp, rulesets/MindFactory.h, rulesets/Missile.h, rulesets/Motion.cpp, rulesets/Motion.h, rulesets/Movement.cpp, rulesets/Movement.h, rulesets/Pedestrian.cpp, rulesets/Pedestrian.h, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_BBox.cpp, rulesets/Py_BBox.h, rulesets/Py_EntityWrapper.h, rulesets/Py_Location.cpp, rulesets/Py_Location.h, rulesets/Py_Map.cpp, rulesets/Py_Map.h, rulesets/Py_Mind.cpp, rulesets/Py_Mind.h, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Operation.h, rulesets/Py_Oplist.cpp, rulesets/Py_Oplist.h, rulesets/Py_Optime.cpp, rulesets/Py_Optime.h, rulesets/Py_Point3D.cpp, rulesets/Py_Point3D.h, rulesets/Py_Property.cpp, rulesets/Py_Property.h, rulesets/Py_Quaternion.cpp, rulesets/Py_Quaternion.h, rulesets/Py_RootEntity.cpp, rulesets/Py_RootEntity.h, rulesets/Py_Statistics.cpp, rulesets/Py_Statistics.h, rulesets/Py_Task.cpp, rulesets/Py_Task.h, rulesets/Py_Thing.cpp, rulesets/Py_Thing.h, rulesets/Py_Vector3D.cpp, rulesets/Py_Vector3D.h, rulesets/Py_World.cpp, rulesets/Py_World.h, rulesets/Py_WorldTime.cpp, rulesets/Py_WorldTime.h, rulesets/PythonArithmeticScript.cpp, rulesets/PythonArithmeticScript.h, rulesets/PythonMindScript.cpp, rulesets/PythonMindScript.h, rulesets/PythonScript.cpp, rulesets/PythonScript.h, rulesets/PythonThingScript.cpp, rulesets/PythonThingScript.h, rulesets/PythonWrapper.cpp, rulesets/PythonWrapper.h, rulesets/Python_API.cpp, rulesets/Python_API.h, rulesets/Python_Script_Utils.h, rulesets/Script.cpp, rulesets/Script.h, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Statistics.cpp, rulesets/Statistics.h, rulesets/StatisticsProperty.cpp, rulesets/StatisticsProperty.h, rulesets/Structure.cpp, rulesets/Structure.h, rulesets/Task.cpp, rulesets/Task.h, rulesets/TaskScript.cpp, rulesets/TaskScript.h, rulesets/TerrainProperty.cpp, rulesets/TerrainProperty.h, rulesets/Thing.cpp, rulesets/Thing.h, rulesets/ThingFactory.cpp, rulesets/ThingFactory.h, rulesets/World.cpp, rulesets/World.h, rulesets/attributes.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/ArithmeticFactory.cpp, server/ArithmeticFactory.h, server/CommClient.cpp, server/CommClient.h, server/CommIdleSocket.cpp, server/CommIdleSocket.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMDNSPublisher.cpp, server/CommMDNSPublisher.h, server/CommMaster.cpp, server/CommMaster.h, server/CommMetaClient.cpp, server/CommMetaClient.h, server/CommPSQLSocket.cpp, server/CommPSQLSocket.h, server/CommPeer.cpp, server/CommPeer.h, server/CommPeerListener.cpp, server/CommPeerListener.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSlaveClient.cpp, server/CommSlaveClient.h, server/CommSlaveListener.cpp, server/CommSlaveListener.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/Connection_methods.h, server/EntityFactory.cpp, server/EntityFactory.h, server/ExternalMind.cpp, server/ExternalMind.h, server/Idle.cpp, server/Idle.h, server/Lobby.cpp, server/Lobby.h, server/Master.cpp, server/Master.h, server/Peer.cpp, server/Peer.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.cpp, server/PersistantThingFactory.h, server/PersistantThingFactory_impl.h, server/Persistor.cpp, server/Persistor.h, server/Persistor_impl.h, server/Player.cpp, server/Player.h, server/Restoration.cpp, server/Restoration.h, server/Restorer.cpp, server/Restorer.h, server/Restorer_impl.h, server/ScriptFactory.cpp, server/ScriptFactory.h, server/ServerRouting.cpp, server/ServerRouting.h, server/ServerRouting_methods.h, server/SlaveClientConnection.cpp, server/SlaveClientConnection.h, server/TaskFactory.cpp, server/TaskFactory.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h, server/server.cpp, server/server.h, server/slave.cpp, tests/Areatest.cpp, tests/BaseEntitytest.cpp, tests/Charactertest.cpp, tests/Containertest.cpp, tests/Creatortest.cpp, tests/EntityExerciser.h, tests/EntityFactorytest.cpp, tests/Entitytest.cpp, tests/Foodtest.cpp, tests/IGEntityExerciser.h, tests/Linetest.cpp, tests/Locationtest.cpp, tests/OOGThingtest.cpp, tests/Planttest.cpp, tests/Propertytest.cpp, tests/Stackabletest.cpp, tests/Structuretest.cpp, tests/Tasktest.cpp, tests/TestWorld.h, tests/Thingtest.cpp, tests/WorldTimetest.cpp, tests/Worldtest.cpp, tests/allOperations.h, tests/collisiontest.cpp, tests/consttest.cpp, tests/distancetest.cpp, tests/emergencetest.cpp, tests/inheritancetest.cpp, tests/logtest.cpp, tests/randomtest.cpp, tests/systemtest.cpp, tests/transformtest.cpp, tests/type_utilstest.cpp, tests/utilitytest.cpp, tools/AdminClient.cpp, tools/AdminClient.h, tools/cyaddrules.cpp, tools/cycmd.cpp, tools/cyconfig.cpp, tools/cyconvertrules.cpp, tools/cyctrl.cpp, tools/cydbload.cpp, tools/cydumprules.cpp, tools/cyisoload.cpp, tools/cyloadrules.cpp, tools/cypasswd.cpp, tools/cywatchdog.cpp: Replace the copyright and license statements with new versions that include disclaimer of warranty, and permit distribution under later versions of the GPL.
2006-01-19 02:17:06 +00:00
// Cyphesis Online RPG Server and AI Engine
// Copyright (C) 2000-2005 Alistair Riddoch
2006-01-19 Al Riddoch <alriddoch@zepler.org> * aiclient/ClientAccount.cpp, aiclient/ClientAccount.h, aiclient/ClientConnection.cpp, aiclient/ClientConnection.h, aiclient/client.cpp, aiclient/client.h, client/BaseClient.cpp, client/BaseClient.h, client/CharacterClient.cpp, client/CharacterClient.h, client/ClientConnection.cpp, client/ClientConnection.h, client/CreatorClient.cpp, client/CreatorClient.h, client/ObserverClient.cpp, client/ObserverClient.h, client/Py_CreatorClient.cpp, client/Py_CreatorClient.h, client/client.cpp, client/define_world.cpp, client/define_world.h, common/Add.h, common/Affect.h, common/AtlasFileLoader.cpp, common/AtlasFileLoader.h, common/Attack.h, common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.cpp, common/BaseWorld.h, common/Burn.h, common/Chop.h, common/Connect.h, common/CustomOp.cpp, common/CustomOp.h, common/CustomOp_impl.h, common/Cut.h, common/Database.cpp, common/Database.h, common/Delve.h, common/Dig.h, common/Eat.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/Generic.h, common/Load.h, common/Monitor.h, common/Mow.h, common/Nourish.h, common/OOGThing.cpp, common/OOGThing.h, common/Property.cpp, common/Property.h, common/Property_impl.h, common/Save.h, common/Setup.h, common/Tick.h, common/Unseen.h, common/Update.h, common/Use.h, common/Wield.h, common/accountbase.cpp, common/accountbase.h, common/const.cpp, common/const.h, common/custom.cpp, common/debug.h, common/globals.cpp, common/globals.h, common/id.cpp, common/id.h, common/inheritance.cpp, common/inheritance.h, common/inheritance_impl.h, common/log.cpp, common/log.h, common/newid.cpp, common/nls.h, common/op_switch.h, common/operations.cpp, common/operations.h, common/random.h, common/refno.h, common/serialno.cpp, common/serialno.h, common/system.cpp, common/system.h, common/terrain_utils.cpp, common/terrain_utils.h, common/type_utils.h, common/types.h, common/utility.cpp, common/utility.h, modules/DateTime.cpp, modules/DateTime.h, modules/Location.cpp, modules/Location.h, modules/WorldTime.cpp, modules/WorldTime.h, physics/BBox.cpp, physics/BBox.h, physics/Collision.cpp, physics/Collision.h, physics/Quaternion.cpp, physics/Quaternion.h, physics/Vector3D.cpp, physics/Vector3D.h, physics/VectorPol.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/AreaProperty.cpp, rulesets/AreaProperty.h, rulesets/ArithmeticScript.cpp, rulesets/ArithmeticScript.h, rulesets/BaseMind.cpp, rulesets/BaseMind.h, rulesets/CalendarProperty.cpp, rulesets/CalendarProperty.h, rulesets/Character.cpp, rulesets/Character.h, rulesets/Combat.cpp, rulesets/Combat.h, rulesets/Container.cpp, rulesets/Container.h, rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityProperties.cpp, rulesets/Entity_getLocation.h, rulesets/Fell.cpp, rulesets/Fell.h, rulesets/Food.cpp, rulesets/Food.h, rulesets/Line.cpp, rulesets/Line.h, rulesets/LineProperty.cpp, rulesets/LineProperty.h, rulesets/MemEntity.cpp, rulesets/MemEntity.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/MemMap_methods.h, rulesets/MindFactory.cpp, rulesets/MindFactory.h, rulesets/Missile.h, rulesets/Motion.cpp, rulesets/Motion.h, rulesets/Movement.cpp, rulesets/Movement.h, rulesets/Pedestrian.cpp, rulesets/Pedestrian.h, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_BBox.cpp, rulesets/Py_BBox.h, rulesets/Py_EntityWrapper.h, rulesets/Py_Location.cpp, rulesets/Py_Location.h, rulesets/Py_Map.cpp, rulesets/Py_Map.h, rulesets/Py_Mind.cpp, rulesets/Py_Mind.h, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Operation.h, rulesets/Py_Oplist.cpp, rulesets/Py_Oplist.h, rulesets/Py_Optime.cpp, rulesets/Py_Optime.h, rulesets/Py_Point3D.cpp, rulesets/Py_Point3D.h, rulesets/Py_Property.cpp, rulesets/Py_Property.h, rulesets/Py_Quaternion.cpp, rulesets/Py_Quaternion.h, rulesets/Py_RootEntity.cpp, rulesets/Py_RootEntity.h, rulesets/Py_Statistics.cpp, rulesets/Py_Statistics.h, rulesets/Py_Task.cpp, rulesets/Py_Task.h, rulesets/Py_Thing.cpp, rulesets/Py_Thing.h, rulesets/Py_Vector3D.cpp, rulesets/Py_Vector3D.h, rulesets/Py_World.cpp, rulesets/Py_World.h, rulesets/Py_WorldTime.cpp, rulesets/Py_WorldTime.h, rulesets/PythonArithmeticScript.cpp, rulesets/PythonArithmeticScript.h, rulesets/PythonMindScript.cpp, rulesets/PythonMindScript.h, rulesets/PythonScript.cpp, rulesets/PythonScript.h, rulesets/PythonThingScript.cpp, rulesets/PythonThingScript.h, rulesets/PythonWrapper.cpp, rulesets/PythonWrapper.h, rulesets/Python_API.cpp, rulesets/Python_API.h, rulesets/Python_Script_Utils.h, rulesets/Script.cpp, rulesets/Script.h, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Statistics.cpp, rulesets/Statistics.h, rulesets/StatisticsProperty.cpp, rulesets/StatisticsProperty.h, rulesets/Structure.cpp, rulesets/Structure.h, rulesets/Task.cpp, rulesets/Task.h, rulesets/TaskScript.cpp, rulesets/TaskScript.h, rulesets/TerrainProperty.cpp, rulesets/TerrainProperty.h, rulesets/Thing.cpp, rulesets/Thing.h, rulesets/ThingFactory.cpp, rulesets/ThingFactory.h, rulesets/World.cpp, rulesets/World.h, rulesets/attributes.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/ArithmeticFactory.cpp, server/ArithmeticFactory.h, server/CommClient.cpp, server/CommClient.h, server/CommIdleSocket.cpp, server/CommIdleSocket.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMDNSPublisher.cpp, server/CommMDNSPublisher.h, server/CommMaster.cpp, server/CommMaster.h, server/CommMetaClient.cpp, server/CommMetaClient.h, server/CommPSQLSocket.cpp, server/CommPSQLSocket.h, server/CommPeer.cpp, server/CommPeer.h, server/CommPeerListener.cpp, server/CommPeerListener.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSlaveClient.cpp, server/CommSlaveClient.h, server/CommSlaveListener.cpp, server/CommSlaveListener.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/Connection_methods.h, server/EntityFactory.cpp, server/EntityFactory.h, server/ExternalMind.cpp, server/ExternalMind.h, server/Idle.cpp, server/Idle.h, server/Lobby.cpp, server/Lobby.h, server/Master.cpp, server/Master.h, server/Peer.cpp, server/Peer.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.cpp, server/PersistantThingFactory.h, server/PersistantThingFactory_impl.h, server/Persistor.cpp, server/Persistor.h, server/Persistor_impl.h, server/Player.cpp, server/Player.h, server/Restoration.cpp, server/Restoration.h, server/Restorer.cpp, server/Restorer.h, server/Restorer_impl.h, server/ScriptFactory.cpp, server/ScriptFactory.h, server/ServerRouting.cpp, server/ServerRouting.h, server/ServerRouting_methods.h, server/SlaveClientConnection.cpp, server/SlaveClientConnection.h, server/TaskFactory.cpp, server/TaskFactory.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h, server/server.cpp, server/server.h, server/slave.cpp, tests/Areatest.cpp, tests/BaseEntitytest.cpp, tests/Charactertest.cpp, tests/Containertest.cpp, tests/Creatortest.cpp, tests/EntityExerciser.h, tests/EntityFactorytest.cpp, tests/Entitytest.cpp, tests/Foodtest.cpp, tests/IGEntityExerciser.h, tests/Linetest.cpp, tests/Locationtest.cpp, tests/OOGThingtest.cpp, tests/Planttest.cpp, tests/Propertytest.cpp, tests/Stackabletest.cpp, tests/Structuretest.cpp, tests/Tasktest.cpp, tests/TestWorld.h, tests/Thingtest.cpp, tests/WorldTimetest.cpp, tests/Worldtest.cpp, tests/allOperations.h, tests/collisiontest.cpp, tests/consttest.cpp, tests/distancetest.cpp, tests/emergencetest.cpp, tests/inheritancetest.cpp, tests/logtest.cpp, tests/randomtest.cpp, tests/systemtest.cpp, tests/transformtest.cpp, tests/type_utilstest.cpp, tests/utilitytest.cpp, tools/AdminClient.cpp, tools/AdminClient.h, tools/cyaddrules.cpp, tools/cycmd.cpp, tools/cyconfig.cpp, tools/cyconvertrules.cpp, tools/cyctrl.cpp, tools/cydbload.cpp, tools/cydumprules.cpp, tools/cyisoload.cpp, tools/cyloadrules.cpp, tools/cypasswd.cpp, tools/cywatchdog.cpp: Replace the copyright and license statements with new versions that include disclaimer of warranty, and permit distribution under later versions of the GPL.
2006-01-19 02:17:06 +00:00
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// $Id$
#include <Python.h>
#include "EntityBuilder.h"
#include "CorePropertyManager.h"
#include "EntityFactory.h"
#include "ScriptFactory.h"
#include "TaskFactory.h"
2009-03-24 03:08:45 +00:00
#include "Persistence.h"
#include "Player.h"
#include "rulesets/Thing.h"
#include "rulesets/MindFactory.h"
#include "rulesets/Character.h"
#include "rulesets/Creator.h"
#include "rulesets/Plant.h"
#include "rulesets/Stackable.h"
#include "rulesets/World.h"
#include "rulesets/Python_Script_Utils.h"
#include "common/id.h"
#include "common/log.h"
#include "common/debug.h"
#include "common/globals.h"
#include "common/const.h"
#include "common/Inheritance.h"
#include "common/AtlasFileLoader.h"
#include "common/random.h"
#include "common/compose.hpp"
#include "common/Monitors.h"
#include "common/Property.h"
2008-09-08 Al Riddoch <alriddoch@googlemail.com> * rulesets/ActivePropertyFactory_impl.h: Re-work the active property factories so they just pass handler information to the property classes rather than installing it themselves, so the property can now handle installing the handlers each time they are installed on an entity, making class default properties work. * client/ClientPropertyManager.cpp, client/ClientPropertyManager.h, common/PropertyFactory.h, common/PropertyFactory_impl.h, common/PropertyManager.h, rulesets/ActivePropertyFactory.h, server/CorePropertyManager.cpp, server/CorePropertyManager.h: Modify the property manager and property factory interfaces so they do not take a pointer to the owner, as this is never required any more. * rulesets/Character.cpp, rulesets/Entity.cpp: Modify code that uses property managers to use the new interface. * rulesets/SolidProperty.cpp, rulesets/SolidProperty.h: Make use of the bool flag to implement this, preventing it from being tied to having a pointer to the owner at creation time. * rulesets/StatusProperty.cpp, rulesets/StatusProperty.h: Remove the need for an owner pointer at construction time by using the apply method. * rulesets/TerrainModProperty.cpp, rulesets/TerrainModProperty.h: Use new MultiActivePropertyManager and install method to handle installing handlers rather than relying on the factory to do it. * server/CorePropertyManager.cpp: Change many of the property factories now that none get get an owner pointer. * server/EntityFactory.cpp: Set up default properties on all type nodes when a new class is installed, and don't apply instance properties based on class defaults, relying on class properties. * rulesets/Entity.cpp: Remove hard coded BBox property now that the functionality is handled by a more special property.
2008-09-08 00:17:08 +00:00
#include "common/TypeNode.h"
#include <Atlas/Message/Element.h>
#include <Atlas/Objects/Entity.h>
#include <Atlas/Objects/RootOperation.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif // HAS_DIRENT_H
2004-12-03 Al Riddoch <alriddoch@zepler.org> * client/BaseClient.cpp, client/BaseClient.h, client/CharacterClient.cpp, client/CharacterClient.h, client/ClientConnection.cpp, client/ClientConnection.h, client/CreatorClient.cpp, client/CreatorClient.h, client/Py_CreatorClient.cpp, common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.h, common/custom.cpp, common/inheritance.cpp, common/inheritance.h, common/inheritance_impl.h, common/op_switch.h, common/type_utils.h, common/types.h, common/utility.cpp, common/utility.h, modules/Location.cpp, rulesets/BaseMind.cpp, rulesets/BaseMind.h, rulesets/Character.cpp, rulesets/Character.h, rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityProperties.cpp, rulesets/Entity_getLocation.h, rulesets/Food.cpp, rulesets/Food.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/Missile.h, rulesets/Pedestrian.cpp, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp, rulesets/Py_Object.cpp, rulesets/Py_Operation.cpp, rulesets/Py_Operation.h, rulesets/Py_Thing.cpp, rulesets/PythonMindScript.h, rulesets/PythonScript.h, rulesets/PythonThingScript.h, rulesets/Python_API.cpp, rulesets/Script.cpp, rulesets/Script.h, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Thing.cpp, rulesets/Thing.h, rulesets/World.cpp, rulesets/World.h, server/Account.cpp, server/Account.h server/Admin.cpp, server/Admin.h, server/CommClient.cpp, server/Connection.cpp, server/Connection.h, server/EntityFactory.cpp, server/EntityFactory.h, server/Lobby.cpp, server/Lobby.h, server/Persistance.cpp, server/Persistance.h, server/Persistor.cpp, server/Player.cpp, server/Player.h, server/ServerRouting.cpp, server/ServerRouting.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h, tests/Areatest.cpp, tests/Charactertest.cpp, tests/Creatortest.cpp, tests/EntityExerciser.h, tests/Entitytest.cpp, tests/Foodtest.cpp, tests/IGEntityExerciser.h, tests/Linetest.cpp, tests/Planttest.cpp, tests/Stackabletest.cpp, tests/Structuretest.cpp, tests/Thingtest.cpp, tests/Worldtest.cpp, tests/allOperations.h, tests/inheritancetest.cpp, tests/utilitytest.cpp, tools/cycmd.cpp: Modify the entity interface so that all Operation methods take references to RootOperation, as its cleaner, and requires less nasty casts. Clean up operations in headers generally.
2004-12-03 14:49:13 +00:00
using Atlas::Message::Element;
using Atlas::Message::MapType;
using Atlas::Message::ListType;
using Atlas::Objects::Root;
using Atlas::Objects::Entity::RootEntity;
2004-12-03 Al Riddoch <alriddoch@zepler.org> * client/BaseClient.cpp, client/BaseClient.h, client/CharacterClient.cpp, client/CharacterClient.h, client/ClientConnection.cpp, client/ClientConnection.h, client/CreatorClient.cpp, client/CreatorClient.h, client/Py_CreatorClient.cpp, common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.h, common/custom.cpp, common/inheritance.cpp, common/inheritance.h, common/inheritance_impl.h, common/op_switch.h, common/type_utils.h, common/types.h, common/utility.cpp, common/utility.h, modules/Location.cpp, rulesets/BaseMind.cpp, rulesets/BaseMind.h, rulesets/Character.cpp, rulesets/Character.h, rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityProperties.cpp, rulesets/Entity_getLocation.h, rulesets/Food.cpp, rulesets/Food.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/Missile.h, rulesets/Pedestrian.cpp, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp, rulesets/Py_Object.cpp, rulesets/Py_Operation.cpp, rulesets/Py_Operation.h, rulesets/Py_Thing.cpp, rulesets/PythonMindScript.h, rulesets/PythonScript.h, rulesets/PythonThingScript.h, rulesets/Python_API.cpp, rulesets/Script.cpp, rulesets/Script.h, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Thing.cpp, rulesets/Thing.h, rulesets/World.cpp, rulesets/World.h, server/Account.cpp, server/Account.h server/Admin.cpp, server/Admin.h, server/CommClient.cpp, server/Connection.cpp, server/Connection.h, server/EntityFactory.cpp, server/EntityFactory.h, server/Lobby.cpp, server/Lobby.h, server/Persistance.cpp, server/Persistance.h, server/Persistor.cpp, server/Player.cpp, server/Player.h, server/ServerRouting.cpp, server/ServerRouting.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h, tests/Areatest.cpp, tests/Charactertest.cpp, tests/Creatortest.cpp, tests/EntityExerciser.h, tests/Entitytest.cpp, tests/Foodtest.cpp, tests/IGEntityExerciser.h, tests/Linetest.cpp, tests/Planttest.cpp, tests/Stackabletest.cpp, tests/Structuretest.cpp, tests/Thingtest.cpp, tests/Worldtest.cpp, tests/allOperations.h, tests/inheritancetest.cpp, tests/utilitytest.cpp, tools/cycmd.cpp: Modify the entity interface so that all Operation methods take references to RootOperation, as its cleaner, and requires less nasty casts. Clean up operations in headers generally.
2004-12-03 14:49:13 +00:00
using String::compose;
typedef std::map<std::string, Atlas::Objects::Root> RootDict;
static const bool debug_flag = false;
EntityBuilder * EntityBuilder::m_instance = NULL;
EntityBuilder::EntityBuilder(BaseWorld & w) : m_world(w)
{
2009-03-22 15:18:10 +00:00
installFactory("world", "game_entity", new EntityFactory<World>());
EntityFactory<Thing> * tft = new EntityFactory<Thing>();
installFactory("thing", "game_entity", tft);
2009-03-22 15:18:10 +00:00
installFactory("character", "thing", new EntityFactory<Character>());
installFactory("creator", "character", new EntityFactory<Creator>());
installFactory("plant", "thing", new EntityFactory<Plant>());
installFactory("stackable", "thing", new EntityFactory<Stackable>());
// The property manager instance installs itself at construction time.
new CorePropertyManager();
}
EntityBuilder::~EntityBuilder()
{
delete PropertyManager::instance();
}
/// \brief Build and populate a new entity object.
///
/// A factory is found for the type of entity, and invoked to create the object
/// instance. If the type has a script factory, this is invoked to create the
/// associates script object which is attached to the entity instance.
/// The attribute values are then set on the instance, taking into account
/// the defaults for the class, and those inherited from parent classes, and
/// the values specified for this instance. The essential location data for
/// this instance is then set up. The final block of code relating to
/// persistence is legacy, and should never be invoked.
/// @param id The string identifier of the new entity.
/// @param intId The integer identifier of the new entity.
/// @param type The string specifying the type of entity.
/// @param attributes A mapping of attribute values to set on the entity.
Entity * EntityBuilder::newEntity(const std::string & id, long intId,
const std::string & type,
const RootEntity & attributes) const
{
debug(std::cout << "EntityFactor::newEntity()" << std::endl << std::flush;);
Entity * thing = 0;
FactoryDict::const_iterator I = m_entityFactories.find(type);
if (I == m_entityFactories.end()) {
return 0;
}
EntityKit * factory = I->second;
2009-03-22 15:18:10 +00:00
thing = factory->newEntity(id, intId);
if (thing == 0) {
return 0;
}
debug( std::cout << "[" << type << "]"
<< std::endl << std::flush;);
thing->setType(factory->m_type);
// Sort out python object
if (factory->m_scriptFactory != 0) {
debug(std::cout << "Class " << type << " has a python class"
<< std::endl << std::flush;);
factory->m_scriptFactory->addScript(thing);
}
//
factory->populate(*thing);
MapType attrs = attributes->asMessage();
// Apply the attribute values
thing->merge(attrs);
// Then set up the default class properties
2008-09-08 Al Riddoch <alriddoch@googlemail.com> * rulesets/ActivePropertyFactory_impl.h: Re-work the active property factories so they just pass handler information to the property classes rather than installing it themselves, so the property can now handle installing the handlers each time they are installed on an entity, making class default properties work. * client/ClientPropertyManager.cpp, client/ClientPropertyManager.h, common/PropertyFactory.h, common/PropertyFactory_impl.h, common/PropertyManager.h, rulesets/ActivePropertyFactory.h, server/CorePropertyManager.cpp, server/CorePropertyManager.h: Modify the property manager and property factory interfaces so they do not take a pointer to the owner, as this is never required any more. * rulesets/Character.cpp, rulesets/Entity.cpp: Modify code that uses property managers to use the new interface. * rulesets/SolidProperty.cpp, rulesets/SolidProperty.h: Make use of the bool flag to implement this, preventing it from being tied to having a pointer to the owner at creation time. * rulesets/StatusProperty.cpp, rulesets/StatusProperty.h: Remove the need for an owner pointer at construction time by using the apply method. * rulesets/TerrainModProperty.cpp, rulesets/TerrainModProperty.h: Use new MultiActivePropertyManager and install method to handle installing handlers rather than relying on the factory to do it. * server/CorePropertyManager.cpp: Change many of the property factories now that none get get an owner pointer. * server/EntityFactory.cpp: Set up default properties on all type nodes when a new class is installed, and don't apply instance properties based on class defaults, relying on class properties. * rulesets/Entity.cpp: Remove hard coded BBox property now that the functionality is handled by a more special property.
2008-09-08 00:17:08 +00:00
PropertyDict::const_iterator J = factory->m_type->defaults().begin();
PropertyDict::const_iterator Jend = factory->m_type->defaults().end();
for (; J != Jend; ++J) {
PropertyBase * prop = J->second;
// If a property is in the class it won't have been installed
// as setAttr() checks
2008-09-08 Al Riddoch <alriddoch@googlemail.com> * rulesets/ActivePropertyFactory_impl.h: Re-work the active property factories so they just pass handler information to the property classes rather than installing it themselves, so the property can now handle installing the handlers each time they are installed on an entity, making class default properties work. * client/ClientPropertyManager.cpp, client/ClientPropertyManager.h, common/PropertyFactory.h, common/PropertyFactory_impl.h, common/PropertyManager.h, rulesets/ActivePropertyFactory.h, server/CorePropertyManager.cpp, server/CorePropertyManager.h: Modify the property manager and property factory interfaces so they do not take a pointer to the owner, as this is never required any more. * rulesets/Character.cpp, rulesets/Entity.cpp: Modify code that uses property managers to use the new interface. * rulesets/SolidProperty.cpp, rulesets/SolidProperty.h: Make use of the bool flag to implement this, preventing it from being tied to having a pointer to the owner at creation time. * rulesets/StatusProperty.cpp, rulesets/StatusProperty.h: Remove the need for an owner pointer at construction time by using the apply method. * rulesets/TerrainModProperty.cpp, rulesets/TerrainModProperty.h: Use new MultiActivePropertyManager and install method to handle installing handlers rather than relying on the factory to do it. * server/CorePropertyManager.cpp: Change many of the property factories now that none get get an owner pointer. * server/EntityFactory.cpp: Set up default properties on all type nodes when a new class is installed, and don't apply instance properties based on class defaults, relying on class properties. * rulesets/Entity.cpp: Remove hard coded BBox property now that the functionality is handled by a more special property.
2008-09-08 00:17:08 +00:00
prop->install(thing);
// The property will have been applied if it has an overriden
// value, so we only apply it the value is still default.
if (attrs.find(J->first) == attrs.end()) {
prop->apply(thing);
}
2008-09-08 Al Riddoch <alriddoch@googlemail.com> * rulesets/ActivePropertyFactory_impl.h: Re-work the active property factories so they just pass handler information to the property classes rather than installing it themselves, so the property can now handle installing the handlers each time they are installed on an entity, making class default properties work. * client/ClientPropertyManager.cpp, client/ClientPropertyManager.h, common/PropertyFactory.h, common/PropertyFactory_impl.h, common/PropertyManager.h, rulesets/ActivePropertyFactory.h, server/CorePropertyManager.cpp, server/CorePropertyManager.h: Modify the property manager and property factory interfaces so they do not take a pointer to the owner, as this is never required any more. * rulesets/Character.cpp, rulesets/Entity.cpp: Modify code that uses property managers to use the new interface. * rulesets/SolidProperty.cpp, rulesets/SolidProperty.h: Make use of the bool flag to implement this, preventing it from being tied to having a pointer to the owner at creation time. * rulesets/StatusProperty.cpp, rulesets/StatusProperty.h: Remove the need for an owner pointer at construction time by using the apply method. * rulesets/TerrainModProperty.cpp, rulesets/TerrainModProperty.h: Use new MultiActivePropertyManager and install method to handle installing handlers rather than relying on the factory to do it. * server/CorePropertyManager.cpp: Change many of the property factories now that none get get an owner pointer. * server/EntityFactory.cpp: Set up default properties on all type nodes when a new class is installed, and don't apply instance properties based on class defaults, relying on class properties. * rulesets/Entity.cpp: Remove hard coded BBox property now that the functionality is handled by a more special property.
2008-09-08 00:17:08 +00:00
}
// Get location from entity, if it is present
// The default attributes cannot contain info on location
if (attributes->hasAttrFlag(Atlas::Objects::Entity::LOC_FLAG)) {
const std::string & loc_id = attributes->getLoc();
thing->m_location.m_loc = m_world.getEntity(loc_id);
}
if (thing->m_location.m_loc == 0) {
// If no info was provided, put the entity in the game world
thing->m_location.m_loc = &m_world.m_gameWorld;
}
thing->m_location.readFromEntity(attributes);
if (!thing->m_location.pos().isValid()) {
// If no position coords were provided, put it somewhere near origin
thing->m_location.m_pos = Point3D(uniform(-8,8), uniform(-8,8), 0);
}
if (thing->m_location.velocity().isValid()) {
if (attributes->hasAttrFlag(Atlas::Objects::Entity::VELOCITY_FLAG)) {
log(ERROR, compose("EntityBuilder::newEntity(%1, %2): "
"Entity has velocity set from the attributes "
"given by the creator", id, type));
} else {
log(ERROR, compose("EntityBuilder::newEntity(%1, %2): Entity has "
"velocity set from an unknown source",
id, type));
}
thing->m_location.m_velocity.setValid(false);
}
return thing;
}
/// \brief Build and populate a new task object.
///
/// @param name The name of the task type.
/// @param owner The character entity that owns the task.
Task * EntityBuilder::newTask(const std::string & name, Character & owner) const
{
TaskFactoryDict::const_iterator I = m_taskFactories.find(name);
if (I == m_taskFactories.end()) {
return 0;
}
return I->second->newTask(owner);
}
/// \brief Build a new task object activated by the described event.
///
/// An event is described in terms of the tool type used to cause it,
/// the type of operation being performed using the tool and the type of
/// the target object the tool is being used on. If a match is found for
/// this event, a task object is instanced to track the progress of the
/// result of the event.
/// @param tool The type of tool activating the event.
/// @param op The type of operation being performed with the tool.
/// @param target The type of entity the operation is being performed on.
/// @param owner The character entity activating the task.
Task * EntityBuilder::activateTask(const std::string & tool,
const std::string & op,
const std::string & target,
Character & owner) const
{
TaskFactoryActivationDict::const_iterator I = m_taskActivations.find(tool);
if (I == m_taskActivations.end()) {
return 0;
}
const TaskFactoryMultimap & dict = I->second;
TaskFactoryMultimap::const_iterator J = dict.lower_bound(op);
if (J == dict.end()) {
return 0;
}
TaskFactoryMultimap::const_iterator Jend = dict.upper_bound(op);
for (; J != Jend; ++J) {
if (!J->second->m_target.empty()) {
if (!Inheritance::instance().isTypeOf(target, J->second->m_target)) {
debug( std::cout << target << " is not a " << J->second->m_target
<< std::endl << std::flush; );
continue;
}
}
return J->second->newTask(owner);
}
return 0;
}
/// \brief Clear out all the factory objects owned by the entity builder.
void EntityBuilder::flushFactories()
{
FactoryDict::const_iterator Iend = m_entityFactories.end();
for (FactoryDict::const_iterator I = m_entityFactories.begin(); I != Iend; ++I) {
delete I->second;
}
m_entityFactories.clear();
TaskFactoryDict::const_iterator K = m_taskFactories.begin();
TaskFactoryDict::const_iterator Kend = m_taskFactories.end();
for (; K != Kend; ++K) {
delete K->second;
}
m_taskFactories.clear();
}
int EntityBuilder::populateEntityFactory(const std::string & class_name,
EntityKit * factory,
const MapType & class_desc)
{
// assert(class_name == class_desc->getId());
// Establish whether this rule has an associated script, and
// if so, use it.
MapType::const_iterator J = class_desc.find("script");
MapType::const_iterator Jend = class_desc.end();
if (J != Jend && J->second.isMap()) {
2004-08-07 Al Riddoch <alriddoch@zepler.org> * common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.h, common/Database.cpp, common/Database.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/accountbase.cpp, common/accountbase.h, common/custom.cpp, common/inheritance.cpp, common/inheritance.h, common/operations.h, common/type_utils.h, common/utility.cpp, common/utility.h, modules/Location.cpp, modules/Location.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/BaseMind.cpp, rulesets/Character.cpp, rulesets/Character.h, rulesets/Creator.cpp, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/Entity_getLocation.h, rulesets/Food.cpp, rulesets/Line.cpp, rulesets/Line.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/Pedestrian.cpp, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Thing.cpp, rulesets/Python_API.cpp, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Thing.cpp, rulesets/World.cpp, rulesets/World.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/CommClient.cpp, server/CommClient.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMetaClient.h, server/CommPSQLSocket.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/EntityFactory.cpp, server/EntityFactory.h, server/Lobby.cpp, server/Lobby.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.h, server/Persistor.cpp, server/Player.cpp, server/Player.h, server/Restorer.h, server/Restorer_impl.h, server/ServerRouting.cpp, server/ServerRouting.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h: Convert code to using Atlas Message typedefs as found in Atlas-C++ 0.6 to aid conversion later.
2004-08-16 14:26:47 +00:00
const MapType & script = J->second.asMap();
J = script.find("name");
if (J == script.end() || !J->second.isString()) {
log(ERROR, compose("Entity \"%1\" script has no name.",
class_name));
return -1;
}
const std::string & script_name = J->second.String();
J = script.find("language");
if (J == script.end() || !J->second.isString()) {
log(ERROR, compose("Entity \"%1\" script has no language.",
class_name));
return -1;
}
const std::string & script_language = J->second.String();
if (script_language != "python") {
log(ERROR, compose("Entity \"%1\" script has unknown language "
"\"%2\".", class_name, script_language));
return -1;
}
std::string::size_type ptr = script_name.rfind(".");
if (ptr == std::string::npos) {
log(ERROR, compose("Entity \"%1\" python script has a bad class "
"name \"%2\".", class_name, script_name));
return -1;
}
std::string script_package = script_name.substr(0, ptr);
std::string script_class = script_name.substr(ptr + 1);
if (factory->m_scriptFactory != 0) {
if (factory->m_scriptFactory->package() != script_name) {
delete factory->m_scriptFactory;
factory->m_scriptFactory = 0;
}
}
if (factory->m_scriptFactory == 0) {
factory->m_scriptFactory = new PythonScriptFactory(script_package,
script_class);
}
}
// Establish whether this rule has an associated mind rule,
// and handle it.
J = class_desc.find("mind");
if (J != Jend && J->second.isMap()) {
2004-08-07 Al Riddoch <alriddoch@zepler.org> * common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.h, common/Database.cpp, common/Database.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/accountbase.cpp, common/accountbase.h, common/custom.cpp, common/inheritance.cpp, common/inheritance.h, common/operations.h, common/type_utils.h, common/utility.cpp, common/utility.h, modules/Location.cpp, modules/Location.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/BaseMind.cpp, rulesets/Character.cpp, rulesets/Character.h, rulesets/Creator.cpp, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/Entity_getLocation.h, rulesets/Food.cpp, rulesets/Line.cpp, rulesets/Line.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/Pedestrian.cpp, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Thing.cpp, rulesets/Python_API.cpp, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Thing.cpp, rulesets/World.cpp, rulesets/World.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/CommClient.cpp, server/CommClient.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMetaClient.h, server/CommPSQLSocket.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/EntityFactory.cpp, server/EntityFactory.h, server/Lobby.cpp, server/Lobby.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.h, server/Persistor.cpp, server/Player.cpp, server/Player.h, server/Restorer.h, server/Restorer_impl.h, server/ServerRouting.cpp, server/ServerRouting.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h: Convert code to using Atlas Message typedefs as found in Atlas-C++ 0.6 to aid conversion later.
2004-08-16 14:26:47 +00:00
const MapType & script = J->second.asMap();
J = script.find("name");
if (J != script.end() && J->second.isString()) {
const std::string & mindType = J->second.String();
// language is unused. might need it one day
// J = script.find("language");
// if (J != script.end() && J->second.isString()) {
// const std::string & mindLang = J->second.String();
// }
MindFactory::instance()->addMindType(class_name, mindType);
}
}
// Store the default attribute for entities create by this rule.
J = class_desc.find("attributes");
if (J != Jend && J->second.isMap()) {
2004-08-07 Al Riddoch <alriddoch@zepler.org> * common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.h, common/Database.cpp, common/Database.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/accountbase.cpp, common/accountbase.h, common/custom.cpp, common/inheritance.cpp, common/inheritance.h, common/operations.h, common/type_utils.h, common/utility.cpp, common/utility.h, modules/Location.cpp, modules/Location.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/BaseMind.cpp, rulesets/Character.cpp, rulesets/Character.h, rulesets/Creator.cpp, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/Entity_getLocation.h, rulesets/Food.cpp, rulesets/Line.cpp, rulesets/Line.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/Pedestrian.cpp, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Thing.cpp, rulesets/Python_API.cpp, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Thing.cpp, rulesets/World.cpp, rulesets/World.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/CommClient.cpp, server/CommClient.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMetaClient.h, server/CommPSQLSocket.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/EntityFactory.cpp, server/EntityFactory.h, server/Lobby.cpp, server/Lobby.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.h, server/Persistor.cpp, server/Player.cpp, server/Player.h, server/Restorer.h, server/Restorer_impl.h, server/ServerRouting.cpp, server/ServerRouting.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h: Convert code to using Atlas Message typedefs as found in Atlas-C++ 0.6 to aid conversion later.
2004-08-16 14:26:47 +00:00
const MapType & attrs = J->second.asMap();
MapType::const_iterator Kend = attrs.end();
for (MapType::const_iterator K = attrs.begin(); K != Kend; ++K) {
if (!K->second.isMap()) {
log(ERROR, compose("Attribute description in rule %1 is not a "
"map.", class_name));
continue;
}
2004-08-07 Al Riddoch <alriddoch@zepler.org> * common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.h, common/Database.cpp, common/Database.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/accountbase.cpp, common/accountbase.h, common/custom.cpp, common/inheritance.cpp, common/inheritance.h, common/operations.h, common/type_utils.h, common/utility.cpp, common/utility.h, modules/Location.cpp, modules/Location.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/BaseMind.cpp, rulesets/Character.cpp, rulesets/Character.h, rulesets/Creator.cpp, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/Entity_getLocation.h, rulesets/Food.cpp, rulesets/Line.cpp, rulesets/Line.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/Pedestrian.cpp, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Thing.cpp, rulesets/Python_API.cpp, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Thing.cpp, rulesets/World.cpp, rulesets/World.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/CommClient.cpp, server/CommClient.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMetaClient.h, server/CommPSQLSocket.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/EntityFactory.cpp, server/EntityFactory.h, server/Lobby.cpp, server/Lobby.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.h, server/Persistor.cpp, server/Player.cpp, server/Player.h, server/Restorer.h, server/Restorer_impl.h, server/ServerRouting.cpp, server/ServerRouting.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h: Convert code to using Atlas Message typedefs as found in Atlas-C++ 0.6 to aid conversion later.
2004-08-16 14:26:47 +00:00
const MapType & attr = K->second.asMap();
MapType::const_iterator L = attr.find("default");
if (L != attr.end()) {
// Store this value in the defaults for this class
factory->m_classAttributes[K->first] = L->second;
// and merge it with the defaults inherited from the parent
factory->m_attributes[K->first] = L->second;
}
}
}
// Check whether it should be available to players as a playable character.
J = class_desc.find("playable");
if (J != Jend && J->second.isInt()) {
Player::playableTypes.insert(class_name);
}
return 0;
}
int EntityBuilder::populateTaskFactory(const std::string & class_name,
TaskFactory * factory,
const MapType & class_desc)
{
// assert(class_name == class_desc->getId());
return 0;
}
bool EntityBuilder::isTask(const std::string & class_name)
{
if (class_name == "task") {
return true;
}
return (m_taskFactories.find(class_name) != m_taskFactories.end());
}
static void updateChildren(EntityKit * factory)
{
std::set<EntityKit *>::const_iterator I = factory->m_children.begin();
std::set<EntityKit *>::const_iterator Iend = factory->m_children.end();
for (; I != Iend; ++I) {
EntityKit * child_factory = *I;
child_factory->m_attributes = factory->m_attributes;
MapType::const_iterator J = child_factory->m_classAttributes.begin();
MapType::const_iterator Jend = child_factory->m_classAttributes.end();
for (; J != Jend; ++J) {
child_factory->m_attributes[J->first] = J->second;
}
updateChildren(child_factory);
}
}
static void updateChildrenProperties(EntityKit * factory)
{
// Discover the default attributes which are no longer
// present after the update.
std::set<std::string> removed_properties;
PropertyDict & defaults = factory->m_type->defaults();
PropertyDict::const_iterator I = defaults.begin();
PropertyDict::const_iterator Iend = defaults.end();
MapType::const_iterator Jend = factory->m_attributes.end();
for (; I != Iend; ++I) {
if (factory->m_attributes.find(I->first) == Jend) {
debug( std::cout << I->first << " removed" << std::endl; );
removed_properties.insert(I->first);
}
}
// Remove the class properties for the default attributes that
// no longer exist
std::set<std::string>::const_iterator L = removed_properties.begin();
std::set<std::string>::const_iterator Lend = removed_properties.end();
for (; L != Lend; ++L) {
PropertyDict::iterator M = defaults.find(*L);
delete M->second;
defaults.erase(M);
}
// Update the values of existing class properties, and add new class
// properties for added default attributes.
MapType::const_iterator J = factory->m_attributes.begin();
PropertyBase * p;
for (; J != Jend; ++J) {
PropertyDict::const_iterator I = defaults.find(J->first);
if (I == Iend) {
p = PropertyManager::instance()->addProperty(J->first,
J->second.getType());
assert(p != 0);
p->setFlags(flag_class);
defaults[J->first] = p;
} else {
p = I->second;
}
p->set(J->second);
}
// Propagate the changes to all child factories
std::set<EntityKit *>::const_iterator K = factory->m_children.begin();
std::set<EntityKit *>::const_iterator Kend = factory->m_children.end();
for (; K != Kend; ++K) {
EntityKit * child_factory = *K;
updateChildrenProperties(child_factory);
}
}
int EntityBuilder::installTaskClass(const std::string & class_name,
const std::string & parent,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
TaskFactoryDict::const_iterator I = m_taskFactories.find(class_name);
if (I != m_taskFactories.end()) {
log(ERROR, compose("Attempt to install task \"%1\" which is already "
"installed.", class_name));
}
// Establish that this rule has an associated script.
Element script_attr;
if (class_desc->copyAttr("script", script_attr) != 0 ||
!script_attr.isMap()) {
log(ERROR, compose("Task \"%1\" has no script.", class_name));
return -1;
}
const MapType & script = script_attr.Map();
MapType::const_iterator J = script.find("name");
MapType::const_iterator script_end = script.end();
if (J == script_end || !J->second.isString()) {
log(ERROR, compose("Task \"%1\" script has no name.", class_name));
return -1;
}
const std::string & script_name = J->second.String();
J = script.find("language");
if (J == script_end || !J->second.isString()) {
log(ERROR, compose("Task \"%1\" script has no language.", class_name));
return -1;
}
const std::string & script_language = J->second.String();
if (script_language != "python") {
log(ERROR, compose("Task \"%1\" script has unknown language \"%2\".",
class_name, script_language));
return -1;
}
std::string::size_type ptr = script_name.rfind(".");
if (ptr == std::string::npos) {
log(ERROR, compose("Task \"%1\" python script has a bad class "
"name \"%2\".", class_name, script_name));
return -1;
}
std::string script_package = script_name.substr(0, ptr);
std::string script_class = script_name.substr(ptr + 1);
TaskFactory * factory = new PythonTaskScriptFactory(class_name,
script_package,
script_class);
Element activation_attr;
if (class_desc->copyAttr("activation", activation_attr) != 0 ||
!activation_attr.isMap()) {
delete factory;
log(ERROR, compose("Task \"%1\" has no activation.", class_name));
return -1;
}
const MapType & activation = activation_attr.Map();
MapType::const_iterator act_end = activation.end();
J = activation.find("tool");
if (J == act_end || !J->second.isString()) {
delete factory;
log(ERROR, compose("Task \"%1\" activation has no tool.", class_name));
return -1;
}
const std::string & activation_tool = J->second.String();
Inheritance & i = Inheritance::instance();
if (!i.hasClass(activation_tool)) {
delete factory;
waitForRule(class_name, class_desc, activation_tool,
compose("Task \"%1\" is activated by tool \"%2\" which "
"does not exist.", class_name, activation_tool));
return 1;
}
FactoryDict::const_iterator K = m_entityFactories.find(activation_tool);
if (K == m_entityFactories.end()) {
delete factory;
log(ERROR, compose("Task class \"%1\" is activated by tool \"%2\" "
"which is not an entity class.", class_name,
activation_tool));
return -1;
}
EntityKit * tool_factory = K->second;
J = activation.find("operation");
if (J == act_end || !J->second.isString()) {
delete factory;
log(ERROR, compose("Task \"%1\" activation has no operation.",
class_name));
return -1;
}
const std::string & activation_op = J->second.String();
if (!i.hasClass(activation_op)) {
delete factory;
waitForRule(class_name, class_desc, activation_op,
compose("Task \"%1\" is activated by operation \"%2\" "
"which does not exist.", class_name,
activation_op));
return 1;
}
J = activation.find("target");
if (J != act_end) {
if (!J->second.isString()) {
delete factory;
log(ERROR, compose("Task \"%1\" activation has \"%2\" target.",
class_name,
Element::typeName(J->second.getType())));
return -1;
}
const std::string & target_base = J->second.String();
if (!i.hasClass(target_base)) {
delete factory;
waitForRule(class_name, class_desc, target_base,
compose("Task \"%1\" is activated on target \"%2\" "
"which does not exist.", class_name,
target_base));
return 1;
}
factory->m_target = target_base;
}
m_taskActivations[activation_tool].insert(std::make_pair(activation_op, factory));
MapType::iterator L = tool_factory->m_classAttributes.find("operations");
if (L == tool_factory->m_classAttributes.end()) {
tool_factory->m_classAttributes["operations"] = ListType(1, activation_op);
tool_factory->m_attributes["operations"] = ListType(1, activation_op);
updateChildren(tool_factory);
updateChildrenProperties(tool_factory);
} else {
if (L->second.isList()) {
ListType::const_iterator M = L->second.List().begin();
for (; M != L->second.List().end() && *M != activation_op; ++M);
if (M == L->second.List().end()) {
L->second.List().push_back(activation_op);
tool_factory->m_attributes[L->first] = L->second.List();
updateChildren(tool_factory);
updateChildrenProperties(tool_factory);
}
}
}
m_taskFactories.insert(std::make_pair(class_name, factory));
i.addChild(class_desc);
return 0;
}
int EntityBuilder::installEntityClass(const std::string & class_name,
const std::string & parent,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
// Get the new factory for this rule
FactoryDict::const_iterator I = m_entityFactories.find(parent);
if (I == m_entityFactories.end()) {
debug(std::cout << "class \"" << class_name
<< "\" has non existant parent \"" << parent
<< "\". Waiting." << std::endl << std::flush;);
waitForRule(class_name, class_desc, parent,
compose("Entity rule \"%1\" has parent \"%2\" which does "
"not exist.", class_name, parent));
return 1;
}
EntityKit * parent_factory = I->second;
EntityKit * factory = parent_factory->duplicateFactory();
if (factory == 0) {
log(ERROR,
compose("Attempt to install rule \"%1\" which has parent \"%2\" "
"which cannot be instantiated", class_name, parent));
return -1;
}
assert(factory->m_parent == parent_factory);
// Copy the defaults from the parent. In populateEntityFactory this may be
// overriden with the defaults for this class.
factory->m_attributes = parent_factory->m_attributes;
if (populateEntityFactory(class_name, factory,
class_desc->asMessage()) != 0) {
delete factory;
return -1;
}
debug(std::cout << "INSTALLING " << class_name << ":" << parent
<< std::endl << std::flush;);
// Install the factory in place.
installFactory(class_name, parent, factory, class_desc);
2008-09-08 Al Riddoch <alriddoch@googlemail.com> * rulesets/ActivePropertyFactory_impl.h: Re-work the active property factories so they just pass handler information to the property classes rather than installing it themselves, so the property can now handle installing the handlers each time they are installed on an entity, making class default properties work. * client/ClientPropertyManager.cpp, client/ClientPropertyManager.h, common/PropertyFactory.h, common/PropertyFactory_impl.h, common/PropertyManager.h, rulesets/ActivePropertyFactory.h, server/CorePropertyManager.cpp, server/CorePropertyManager.h: Modify the property manager and property factory interfaces so they do not take a pointer to the owner, as this is never required any more. * rulesets/Character.cpp, rulesets/Entity.cpp: Modify code that uses property managers to use the new interface. * rulesets/SolidProperty.cpp, rulesets/SolidProperty.h: Make use of the bool flag to implement this, preventing it from being tied to having a pointer to the owner at creation time. * rulesets/StatusProperty.cpp, rulesets/StatusProperty.h: Remove the need for an owner pointer at construction time by using the apply method. * rulesets/TerrainModProperty.cpp, rulesets/TerrainModProperty.h: Use new MultiActivePropertyManager and install method to handle installing handlers rather than relying on the factory to do it. * server/CorePropertyManager.cpp: Change many of the property factories now that none get get an owner pointer. * server/EntityFactory.cpp: Set up default properties on all type nodes when a new class is installed, and don't apply instance properties based on class defaults, relying on class properties. * rulesets/Entity.cpp: Remove hard coded BBox property now that the functionality is handled by a more special property.
2008-09-08 00:17:08 +00:00
MapType::const_iterator J = factory->m_attributes.begin();
MapType::const_iterator Jend = factory->m_attributes.end();
PropertyBase * p;
for (; J != Jend; ++J) {
p = PropertyManager::instance()->addProperty(J->first,
J->second.getType());
assert(p != 0);
p->set(J->second);
p->setFlags(flag_class);
2008-09-08 Al Riddoch <alriddoch@googlemail.com> * rulesets/ActivePropertyFactory_impl.h: Re-work the active property factories so they just pass handler information to the property classes rather than installing it themselves, so the property can now handle installing the handlers each time they are installed on an entity, making class default properties work. * client/ClientPropertyManager.cpp, client/ClientPropertyManager.h, common/PropertyFactory.h, common/PropertyFactory_impl.h, common/PropertyManager.h, rulesets/ActivePropertyFactory.h, server/CorePropertyManager.cpp, server/CorePropertyManager.h: Modify the property manager and property factory interfaces so they do not take a pointer to the owner, as this is never required any more. * rulesets/Character.cpp, rulesets/Entity.cpp: Modify code that uses property managers to use the new interface. * rulesets/SolidProperty.cpp, rulesets/SolidProperty.h: Make use of the bool flag to implement this, preventing it from being tied to having a pointer to the owner at creation time. * rulesets/StatusProperty.cpp, rulesets/StatusProperty.h: Remove the need for an owner pointer at construction time by using the apply method. * rulesets/TerrainModProperty.cpp, rulesets/TerrainModProperty.h: Use new MultiActivePropertyManager and install method to handle installing handlers rather than relying on the factory to do it. * server/CorePropertyManager.cpp: Change many of the property factories now that none get get an owner pointer. * server/EntityFactory.cpp: Set up default properties on all type nodes when a new class is installed, and don't apply instance properties based on class defaults, relying on class properties. * rulesets/Entity.cpp: Remove hard coded BBox property now that the functionality is handled by a more special property.
2008-09-08 00:17:08 +00:00
factory->m_type->defaults()[J->first] = p;
}
// Add it as a child to its parent.
parent_factory->m_children.insert(factory);
return 0;
}
int EntityBuilder::installOpDefinition(const std::string & class_name,
const std::string & parent,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
Inheritance & i = Inheritance::instance();
if (!i.hasClass(parent)) {
debug(std::cout << "op_definition \"" << class_name
<< "\" has non existant parent \"" << parent
<< "\". Waiting." << std::endl << std::flush;);
waitForRule(class_name, class_desc, parent,
compose("Operation \"%1\" has parent \"%2\" which does "
"not exist.", class_name, parent));
return 1;
}
Atlas::Objects::Root r = atlasOpDefinition(class_name, parent);
if (i.addChild(class_desc) == 0) {
return -1;
}
int op_no = Atlas::Objects::Factories::instance()->addFactory(class_name, &Atlas::Objects::generic_factory);
i.opInstall(class_name, op_no);
return 0;
}
int EntityBuilder::installRule(const std::string & class_name,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
if (class_name.size() > consts::id_len) {
log(ERROR, compose("Rule \"%1\" has name longer than %2 characters. "
"Skipping.", class_name, consts::id_len));
return -1;
}
const std::string & objtype = class_desc->getObjtype();
const std::list<std::string> & parents = class_desc->getParents();
if (parents.empty()) {
log(ERROR, compose("Rule \"%1\" has empty parents. Skipping.",
class_name));
return -1;
}
const std::string & parent = parents.front();
if (parent.empty()) {
log(ERROR, compose("Rule \"%1\" has empty first parent. Skipping.",
class_name));
return -1;
}
if (objtype == "class") {
if (isTask(parent)) {
int ret = installTaskClass(class_name, parent, class_desc);
if (ret != 0) {
return ret;
}
} else {
int ret = installEntityClass(class_name, parent, class_desc);
if (ret != 0) {
return ret;
}
}
} else if (objtype == "op_definition") {
int ret = installOpDefinition(class_name, parent, class_desc);
if (ret != 0) {
return ret;
}
} else {
log(ERROR, compose("Rule \"%1\" has unknown objtype=\"%2\". Skipping.",
class_name, objtype));
return -1;
}
// Install any rules that were waiting for this rule before they
// could be installed
RuleWaitList::iterator I = m_waitingRules.lower_bound(class_name);
RuleWaitList::iterator Iend = m_waitingRules.upper_bound(class_name);
std::map<std::string, Root> readyRules;
for (; I != Iend; ++I) {
const std::string & wClassName = I->second.name;
const Root & wClassDesc = I->second.desc;
readyRules.insert(std::make_pair(wClassName, wClassDesc));
debug(std::cout << "WAITING rule " << wClassName
<< " now ready from " << class_name
<< std::endl << std::flush;);
}
m_waitingRules.erase(class_name);
std::map<std::string, Root>::const_iterator K = readyRules.begin();
std::map<std::string, Root>::const_iterator Kend = readyRules.end();
for (; K != Kend; ++K) {
const std::string & rClassName = K->first;
const Root & rClassDesc = K->second;
installRule(rClassName, rClassDesc);
}
return 0;
}
int EntityBuilder::modifyEntityClass(const std::string & class_name,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
FactoryDict::const_iterator I = m_entityFactories.find(class_name);
if (I == m_entityFactories.end()) {
log(ERROR, compose("Could not find factory for existing entity class "
"\"%1\".", class_name));
return -1;
}
EntityKit * factory = I->second;
assert(factory != 0);
ScriptFactory * script_factory = factory->m_scriptFactory;
if (script_factory != 0) {
script_factory->refreshClass();
}
MapType backup_attributes = factory->m_attributes,
backup_class_attributes = factory->m_classAttributes;
// Copy the defaults from the parent. In populateEntityFactory this may be
// overriden with the defaults for this class.
if (factory->m_parent != 0) {
factory->m_attributes = factory->m_parent->m_attributes;
} else {
// This is non fatal, but nice to know it has happened.
// This should only happen if the client attempted to modify the
// type data for a core hard coded type.
log(ERROR, compose("EntityBuilder::modifyEntityClass: \"%1\" modified "
"by client, but has no parent factory.",
class_name));
factory->m_attributes = MapType();
}
factory->m_classAttributes = MapType();
if (populateEntityFactory(class_name, factory,
class_desc->asMessage()) != 0) {
factory->m_attributes = backup_attributes;
factory->m_classAttributes = backup_class_attributes;
return -1;
}
updateChildren(factory);
updateChildrenProperties(factory);
return 0;
}
int EntityBuilder::modifyTaskClass(const std::string & class_name,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
TaskFactoryDict::const_iterator I = m_taskFactories.find(class_name);
if (I == m_taskFactories.end()) {
log(ERROR, compose("Could not find factory for existing task class "
"\"%1\"", class_name));
return -1;
}
// FIXME Actually update the task factory.
// TaskFactory * factory = I->second;
// assert(factory != 0);
return 0;
}
int EntityBuilder::modifyOpDefinition(const std::string & class_name,
const Root & class_desc)
{
// Nothing to actually do
return 0;
}
int EntityBuilder::modifyRule(const std::string & class_name,
const Root & class_desc)
{
assert(class_name == class_desc->getId());
Root o = Inheritance::instance().getClass(class_name);
if (!o.isValid()) {
log(ERROR, compose("Could not find existing type \"%1\" in "
"inheritance", class_name));
return -1;
}
if (o->getParents().front() == "task") {
return modifyTaskClass(class_name, class_desc);
} else if (class_desc->getObjtype() == "op_definition") {
return modifyOpDefinition(class_name, class_desc);
} else {
return modifyEntityClass(class_name, class_desc);
}
}
/// \brief Mark a rule down as waiting for another.
///
/// Note that a rule cannot yet be installed because it depends on something
/// that has not yet occured, or a more fatal condition has occured.
void EntityBuilder::waitForRule(const std::string & rulename,
const Root & ruledesc,
const std::string & dependent,
const std::string & reason)
{
RuleWaiting rule;
rule.name = rulename;
rule.desc = ruledesc;
rule.reason = reason;
m_waitingRules.insert(std::make_pair(dependent, rule));
}
void EntityBuilder::getRulesFromFiles(std::map<std::string, Root> & rules)
{
std::string filename;
std::string dirname = etc_directory + "/cyphesis/" + ruleset + ".d";
DIR * rules_dir = ::opendir(dirname.c_str());
if (rules_dir == 0) {
filename = etc_directory + "/cyphesis/" + ruleset + ".xml";
AtlasFileLoader f(filename, rules);
if (f.isOpen()) {
log(WARNING, compose("Reading legacy rule data from \"%1\".",
filename));
f.read();
}
return;
}
while (struct dirent * rules_entry = ::readdir(rules_dir)) {
if (rules_entry->d_name[0] == '.') {
continue;
}
filename = dirname + "/" + rules_entry->d_name;
AtlasFileLoader f(filename, rules);
if (!f.isOpen()) {
log(ERROR, compose("Unable to open rule file \"%1\".", filename));
} else {
f.read();
}
}
::closedir(rules_dir);
}
void EntityBuilder::installRules()
{
std::map<std::string, Root> ruleTable;
if (database_flag) {
2009-03-24 03:08:45 +00:00
Persistence * p = Persistence::instance();
p->getRules(ruleTable);
} else {
getRulesFromFiles(ruleTable);
}
if (ruleTable.empty()) {
log(ERROR, "Rule database table contains no rules.");
if (database_flag) {
log(NOTICE, "Attempting to load temporary ruleset from files.");
getRulesFromFiles(ruleTable);
}
}
RootDict::const_iterator Iend = ruleTable.end();
for (RootDict::const_iterator I = ruleTable.begin(); I != Iend; ++I) {
const std::string & class_name = I->first;
const Root & class_desc = I->second;
installRule(class_name, class_desc);
}
// Report on the non-cleared rules.
// Perhaps we can keep them too?
// m_waitingRules.clear();
RuleWaitList::const_iterator J = m_waitingRules.begin();
RuleWaitList::const_iterator Jend = m_waitingRules.end();
for (; J != Jend; ++J) {
log(ERROR, J->second.reason);
}
}
void EntityBuilder::installFactory(const std::string & class_name,
const std::string & parent,
EntityKit * factory,
Root class_desc)
{
assert(factory != 0);
m_entityFactories[class_name] = factory;
Monitors::instance()->watch(compose("created_count{type=%1}", class_name),
new Monitor<int>(factory->m_createdCount));
Inheritance & i = Inheritance::instance();
if (class_desc.isValid()) {
assert(class_desc->getId() == class_name);
assert(class_desc->getParents().front() == parent);
factory->m_type = i.addChild(class_desc);
} else {
factory->m_type = i.addChild(atlasClass(class_name, parent));
}
}
EntityKit * EntityBuilder::getNewFactory(const std::string & parent)
{
FactoryDict::const_iterator I = m_entityFactories.find(parent);
if (I == m_entityFactories.end()) {
return 0;
}
return I->second->duplicateFactory();
}