Programming and other useless stuff: Stressful life...

Wednesday, August 13, 2008

Stressful life...

Gosh... sometimes life can be stressful :) My cousin, who will be my witness (is it called like this?) at my marriage, had some problems with the date. In fact on august 23rd (a saturday) he should have a university exam. Today was the last day I had to confirm the witnesses of my marriage to the major of our town. So... I started asking friends to replace my cousin. Finally, an hour before desk closure at the major hall, my cousin called me to confirm his presence. He managed to move the exam by one week (there are several of those exams and he was pushed into another group). But I can tell you that I had some sleepless nights because of this :)

Phew... back to work. I had some problems concentrating today (missing sleep) and only managed to get some work done in the afternoon. I've been taking a step back from my source code and the overall layout of the Logic implementation. I'm pleased with most of it. Those who carefully ( :) ) read my blog know that I wasn't pleased with the template stuff in the EntityManager. Also, I didn't like the idea of having the components and entities that might be created by a simple new anywhere in the code. I finally decided to use factories for template, entity and component creation.

The factory approach also allowed me to reconsider the create functions for the templates. Remember that I had 2 different create functions? One for the entity template and one for the component template. The factory approach led me to the conclusion that only one function is needed for both. Basically I kept the create function for the entity template which uses a type and a name string. Component templates do have those two strings, too, since they're derived from the template class. Component templates just set the type string into the name string (Currently I think that component templates don't have to be named).

Ok... now I have 2 factories: the template factory and the component factory:

typedef Template* (*templateCreator)(Sidema::String _name);

class TemplateFactory : public Sidema::Singleton
{
public:
// ----------------------------
// Template management.
void registerTemplate( const Sidema::String &_type, templateCreator _func);
void unregisterTemplate( const Sidema::String &_type );
void clearAllTemplates();

Template* createTemplate(const Sidema::String &_type, const Sidema::String &_name );

protected:
// ----------------------------
// Xtructors.
TemplateFactory();
~TemplateFactory();

private:
friend class Sidema::Singleton;

typedef std::map TEMPLATECREATORS;
TEMPLATECREATORS m_templateCreateFunctions;
};

typedef Component* (*componentCreator)(ComponentTemplate *_template);

class ComponentFactory : public Sidema::Singleton
{
public:
// ----------------------------
// Component creator management.
void registerComponent( const Sidema::String &_type, componentCreator _func);
void unregisterComponent( const Sidema::String &_type );
void clearAllComponents();

Component* createComponent(const Sidema::String &_type, ComponentTemplate *_template);

protected:
// ----------------------------
// Xtructors.
ComponentFactory();
~ComponentFactory();

private:
friend class Sidema::Singleton;

typedef std::map COMPONENTCREATORS;
COMPONENTCREATORS m_componentCreateFunctions;
};


The fact that I didn't like the management of the templates within the entity manager led me to implement a template manager. There wasn't much to do since I only had to move some functions from the entity manager to the template manager.

class TemplateManager : public Sidema::Singleton
{
public:
// ----------------------------
// Template management.
bool loadTemplates(Sidema::String _filename);
void unloadTemplates();
EntityTemplate *getTemplate(Sidema::String _name);

protected:
// ----------------------------
// Xtructors.
TemplateManager();
~TemplateManager();

// ----------------------------
// Template management.
bool addTemplate(const Sidema::String &_name, Template *_template);
void removeTemplate(const Sidema::String &_name);
void releaseAllTemplates();

private:
friend class Sidema::Singleton;

typedef std::map TEMPLATEMAP;
TEMPLATEMAP m_templates;
};


As you can see, the template manager returns a pointer to a entity template. The component templates aren't stored in the template manager. In fact, since the component templates are stored within the enitity template (remember: each component template is unique to the entity template it belongs to), there was no need to do so. I could have simply returned a pointer to a template instance, but this would lead to confusion about the basic type of the template. One could think that it might be a component template he just got...

With all this information (in this blog entry and the previous one), I've implemented a translator for the health component. There's only a constructor, a destructor and the create function of the translator (I'm think of renaming the create function to translate or something else because I normally use create to name static functions which create an instance of that very class; nevertheless, the function really creates something: the translated object).

class HealthTemplateTranslator : public ComponentTemplateTranslator
{
public:
HealthTemplateTranslator() {}
~HealthTemplateTranslator() {}

virtual Component *create(ComponentTemplate *_template) const;
};

Component*
HealthTemplateTranslator::create(ComponentTemplate *_template) const
{
HealthComponent *component = NULL;

// Check for valid template.
if ( _template && !_template->getType().compare(HealthComponentTemplate::TEMPLATE_NAME) )
{
// Get the health and create the component.
float maxHealth = 0.0f;
if ( static_cast(_template)->getMaxHealth( maxHealth ) )
{
component = static_cast(ComponentFactory::Instance().createComponent(HealthComponent::COMPONENT_NAME, _template));
if ( component )
{
// Set the health values.
// Note: The current health should be set to the maximum health
// to have at least living entities, when they startup :)
component->setMaxHealth(maxHealth);
component->setCurrentHealth(maxHealth);
}
}
}

return component;
}


Et voila... the returned component is a translated instance of the health component, filled with the data of the health component template.

The next step is to create an entity from an entity template. While this might sound strange, I still have some problems to pinpoint the differences between a static and a dynamic object. Every difference I can think of can be implemented by components... is it possible that I don't need different specializations of entities?!?

Have fun,
Stefan

PS: I once again changed a little bit the css of the blog... I still got comments that the font was a) too bright and b) the letters were not far apart enough... Fixed this with another font :)

Labels: , , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home