Classes | Typedefs | Functions

AESOP Types and Instances
[AESOP Core Libraries]


The Type/Instance library is the key to AESOP extensibility. More...

Collaboration diagram for AESOP Types and Instances:

Classes

class  aesop::ComponentData
 a base class that components can use to provide rich implementations More...
class  aesop::Instance
 A concrete instantiation of an object at a given place. More...
class  aesop::TypeComponentLoader
 Clients of this library need to provide component loaders for anything that they want loaded. More...

Typedefs

typedef std::vector< smart_ptr
< Instance > > 
aesop::vec_instance_t
 vector of instances
typedef void(* aesop::instance_iteration_fn )(smart_ptr< Instance > &instance, void *context)
 a typedef to support iteration of instances.

Functions

virtual void aesop::ComponentData::dump (const char *txt) const throw ()
 for debugging -- called by Instance::dump()
virtual const char * aesop::Instance::getInstanceId (void) const =0 throw ()
 ID of this particular instance (can be non-unique, can be null!).
virtual const char * aesop::Instance::getTypeId (void) const =0 throw ()
 ID of the instance type.
virtual placement_taesop::Instance::getPlacement (void)=0 throw ()
 raw read/write access to placement
virtual void aesop::Instance::setComponentData (const char *componentName, smart_ptr< ComponentData > &data)=0
 provide component data (physics model, 3d model, ai, etc.
virtual smart_ptr< ComponentData > aesop::Instance::getComponentData (const char *componentName)=0
 retrieve component data (physics model, 3d model, ai, etc.)
virtual const Datahashaesop::Instance::getTypeComponentData (const char *componentName)=0
 retrieve raw component data from type
virtual void aesop::Instance::setInstanceData (const char *componentName, smart_ptr< Datahash > &data)=0
 Set raw instance data for the given named component.
virtual smart_ptr< Datahashaesop::Instance::getInstanceData (const char *componentName)=0
 Retrieve raw instance data for the given named component.
virtual void aesop::Instance::dump (const char *txt)=0 throw ()
 for debugging
static smart_ptr< Instance > aesop::Instance::parse (std::istream &stream)
static smart_ptr< Instance > aesop::Instance::create (const char *instanceId, const char *typeId)
virtual const char * aesop::TypeComponentLoader::getComponentName (void) const =0 throw ()
 what type of component does this load? "physics", "model", "ai" ...
virtual const char * aesop::TypeComponentLoader::getLoaderName (void) const =0 throw ()
 what is the name of this loader? "Bob's homemade loader"?
virtual bool aesop::TypeComponentLoader::isMyFormat (const Datahash *componentData, const char *path) const =0
 given the component data, is this something we can load?
virtual smart_ptr< ComponentData > aesop::TypeComponentLoader::loadTS (smart_ptr< Instance > &instance, const Datahash *componentData, const char *path)=0
 go ahead and load the given component for the given instance
void aesop::initializeTypeInstanceLibrary (smart_ptr< story::Story > &story)
 Must initialize the type instance library at the beginning of time!
void aesop::registerTypeComponentLoader (smart_ptr< aesop::TypeComponentLoader > &tcl)
 Static method for registering type component loaders.
void aesop::loadInstances (std::istream &stream,vec_instance_t &instances)
 Load Instance objects from the given stream.
const char * aesop::getKeyWithOverrides (const char *keyName,const Datahash *instanceData,const Datahash *typeData,const Datahash *modelData,eDatahash_Flag flag)
 handy utility method for type component loaders: given the three raw data hashes (instance data, type data, and model data) get the value from the appropriate override source (instance, then type, then model)

Detailed Description


The Type/Instance library is the key to AESOP extensibility.

If you want to extend the framework to add your own graphics/AI/physics/etc., then you should understand how these work. World designers will also need to know how these objects are used. When you place objects in your world, you'll be creating instances, and this framework gives you the ability to customize each instance to some degree, beyond the default behavior of the type.


A type is any sort of thing that can appear in a map. This includes:

A type has an arbitrary number of named properties (called "components"). Some examples of type components are:

The whole purpose of the type/instance library is that although the type can have arbitrary components bound to it, the type doesn't know how they are implemented. This way, the codebase can use Type/Instance objects to keep track of what is in the world, without being bound to how things are actualy implemented.

Different applications will care about different components. For instance, the server won't care about the visual (3D rendering) component at all. The server will mostly care about the physics and AI. The client is the reverse: it will need to render, but won't use the AI. (The client may use the physics for predictive purposes).

The application binding occurs in the main.cpp file (or something similar). During initialization, the application writer provides TypeComponentLoader objects for the components they think the application will need. Most applications are pretty simple: pick the core AESOP libraries you need, register whatever component loaders seem appropriate, and then let the core libraries start execution. The component loaders will be called as needed.

The type/instance library uses a very decoupled model, so that the server can pick up the components of a type that it cares about, without any dependencies on the components it doesn't care about. And similarly for the client. Furthermore, other parts of the codebase only use components through general interfaces, so in most cases you should be able to swap out components (different AI system, different graphics engine, etc.) with minimal impact.


An "instance" is a concrete instance of a type. For example, you could declare a type with ID "chicken", and then populate your map with hundreds of instances of chicken types. And so on.

Every instance has three properties:

In addition, every instance has "component data". This component data is purposely left general, because this core piece of the framework doesn't know what components will be added. All that the Instance knows is that there are ComponentData objects attached to it, each with a name. Some common examples are:

In all of these cases, the component owner will provide rich objects that inherit from the ComponentData base class. If you have an instance, you will need to upcast to the appropriate object as necessary.


Typedef Documentation

typedef std::vector<smart_ptr<Instance> > aesop::vec_instance_t

vector of instances

Definition at line 226 of file typeinst.h.

typedef void(* aesop::instance_iteration_fn)(smart_ptr< Instance > &instance,void *context)

a typedef to support iteration of instances.

Definition at line 230 of file typeinst.h.


Function Documentation

void aesop::ComponentData::dump ( const char *  txt  )  const throw () [virtual, inherited]

for debugging -- called by Instance::dump()

Definition at line 100 of file typeinst.cpp.

virtual const char* aesop::Instance::getInstanceId ( void   )  const throw () [pure virtual, inherited]

ID of this particular instance (can be non-unique, can be null!).

virtual const char* aesop::Instance::getTypeId ( void   )  const throw () [pure virtual, inherited]

ID of the instance type.

virtual placement_t& aesop::Instance::getPlacement ( void   )  throw () [pure virtual, inherited]

raw read/write access to placement

virtual void aesop::Instance::setComponentData ( const char *  componentName,
smart_ptr< ComponentData > &  data 
) [pure virtual, inherited]

provide component data (physics model, 3d model, ai, etc.

). set to null to clear component data

virtual smart_ptr<ComponentData> aesop::Instance::getComponentData ( const char *  componentName  )  [pure virtual, inherited]

retrieve component data (physics model, 3d model, ai, etc.)

virtual const Datahash* aesop::Instance::getTypeComponentData ( const char *  componentName  )  [pure virtual, inherited]

retrieve raw component data from type

virtual void aesop::Instance::setInstanceData ( const char *  componentName,
smart_ptr< Datahash > &  data 
) [pure virtual, inherited]

Set raw instance data for the given named component.

Set to null toclear out instance data for that named comonent.

virtual smart_ptr<Datahash> aesop::Instance::getInstanceData ( const char *  componentName  )  [pure virtual, inherited]

Retrieve raw instance data for the given named component.

Returns null if no data was set for the given component name. This is typically used by TypeComponentLoader objects. Everyone else should use component data from getComponentData().

virtual void aesop::Instance::dump ( const char *  txt  )  throw () [pure virtual, inherited]

for debugging

smart_ptr< Instance > aesop::Instance::parse ( std::istream &  stream  )  [static, inherited]

Definition at line 644 of file typeinst.cpp.

smart_ptr< Instance > aesop::Instance::create ( const char *  instanceId,
const char *  typeId 
) [static, inherited]

Definition at line 671 of file typeinst.cpp.

virtual const char* aesop::TypeComponentLoader::getComponentName ( void   )  const throw () [pure virtual, inherited]

what type of component does this load? "physics", "model", "ai" ...

virtual const char* aesop::TypeComponentLoader::getLoaderName ( void   )  const throw () [pure virtual, inherited]

what is the name of this loader? "Bob's homemade loader"?

virtual bool aesop::TypeComponentLoader::isMyFormat ( const Datahash componentData,
const char *  path 
) const [pure virtual, inherited]

given the component data, is this something we can load?

virtual smart_ptr<ComponentData> aesop::TypeComponentLoader::loadTS ( smart_ptr< Instance > &  instance,
const Datahash componentData,
const char *  path 
) [pure virtual, inherited]

go ahead and load the given component for the given instance

void aesop::initializeTypeInstanceLibrary ( smart_ptr< story::Story > &  story  ) 

Must initialize the type instance library at the beginning of time!

void aesop::registerTypeComponentLoader ( smart_ptr< aesop::TypeComponentLoader > &  tcl  ) 

Static method for registering type component loaders.

Use this method to register your TypeComponentLoader with the framework!

void aesop::loadInstances ( std::istream &  stream,
vec_instance_t &  instances 
)

Load Instance objects from the given stream.

const char * aesop::getKeyWithOverrides ( const char *  keyName,
const Datahash instanceData,
const Datahash typeData,
const Datahash modelData,
eDatahash_Flag  flag 
)

handy utility method for type component loaders: given the three raw data hashes (instance data, type data, and model data) get the value from the appropriate override source (instance, then type, then model)

Caller can use the flag parameter to specify if the key is required or not. If not required, a null can be returned if none of the hashes contain the key. Otherwise, an exception would be thrown.