Extensible factories
This presentation is the property of its rightful owner.
Sponsored Links
1 / 15

Extensible Factories PowerPoint PPT Presentation


  • 125 Views
  • Uploaded on
  • Presentation posted in: General

Extensible Factories. Bonus Material – Not Examinable. Contents. Interface / Factory Recap Limitations of Factory Functions Extensible Factory Functions Extensible Factories Usage. Interfaces Recap. In C++, an interface is a class that has: No member variables

Download Presentation

Extensible Factories

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Extensible factories

Extensible Factories

Bonus Material – Not Examinable


Contents

Contents

  • Interface / Factory Recap

  • Limitations of Factory Functions

  • Extensible Factory Functions

  • Extensible Factories Usage


Interfaces recap

Interfaces Recap

  • In C++, an interface is a class that has:

    • No member variables

    • Only pure virtual functions

      • Prototype with no implementation

  • Only defines functions & does not implement them

    • We cannot create objects with pure virtual functions

  • Inherited implementation classes provide the code

    • A partial implementation is a kind of abstract class

  • An interface class defines the functionality

  • The implementation classes provide the functionality for different contexts


Interface example

Interface Example

class IEntity // Interface

{

public:

virtual void Update( float frameTime ) = 0;

virtual void AI() = 0;

}

// Partial implementation – abstract class

class CMovableEntity : public IEntity

{

public:

void Update( float frameTime ){

m_Position += m_Velocity * frameTime;}

virtual void AI() = 0; // Still pure virtual

protected:

CVector3 m_Position, m_Velocity;

}


Interface example1

Interface Example

// Complete implementation

class CShipEntity : public CMovableEntity

{

public:

void Update( float frameTime ){

m_HP += m_Damage;

CMovableEntity::Update(); // Call base class Update

}

void AI() // (lol)

{

m_Velocity.x = Random(-10.0f, 10.0f);

m_Velocity.z = Random(-10.0f, 10.0f);

}

private:

int m_HP, m_Damage;

}


Factory functions

Factory Functions

  • Factory functions make objects of a specific type

  • Typically used to create an object derived from an interface or abstract class

    • Without coupling to the inherited classes

  • A factory creates specific implementation classes

  • Say we use the IEntity class generally in our code

    • If we want to create a ship entity in our game

    • We create a factory function:

      IEntity* CreateEntity( EntityType type );

    • Now we don’t need to refer to CShipEntity:

      IEntity* newShip = CreateEntity( ShipType );


Factory function example

Factory Function Example

// Factory.h - Can be included anywhere – no coupling

// Enumeration of types created by factory function

enum { ShipType, PlanetType, }; // etc.

IEntity* CreateEntity( EntityType type ); // Prototype

// Factory.cpp - coupled to all types that can be created

#include “CShipEntity.h”

// Factory function – creates objects of a given type

IEntity* CreateEntity( EntityType type ) {

if (type == ShipType)

{ return new CShipEntity;

}

else // ...create other supported types

}


Factory function example1

Factory Function Example

// Game code

// Include factory prototype / entity types

// No linkage to actual entity classes – no coupling

#include “Factory.h”

// ...

// Create entities – no need to refer to actual classes

IEntity* ship1 = CreateEntity( shipType );

IEntity* ship2 = CreateEntity( shipType );

IEntity* planet1 = CreateEntity( planetType );

// ...

// Generic programming with entities

ship1->Update(); // Entity class contains behaviour

ship1->Render();

// etc...


Limitations of factories

Limitations of Factories

  • The factory function needs the definition of CShipEntity, and every other type it creates

    • “CShipEntity.h” must be included for the factory code

    • Usually means factories having their own source file

  • Factories are coupled to all the objects they create

    • So we need to recode/compile the factory every time we add a new type for it to create

  • Can’t add new types at runtime

    • Limits use for scripting / modding etc.


Extensible factories1

Extensible Factories

  • More general approach is an extensible factory

  • A factory that can create objects of any class without needing the specific class definitions

    • It can only create objects with the same base class

    • But only needs the base class definition

  • We must explicitly register each new class before being able to create its objects

    • Unregister them when not needed anymore

  • This can be made quite automatic in C++

    • Using templates to help…


Simple extensible factory class

Simple Extensible Factory Class

  • Provide each inherited class with a “Maker” function, which can create objects of that class

  • Register new types with type ID and “Maker” function ptr

    // Factory to create any class inherited from Ientity

    // Note this is a factory class, not just a function

    class ExtensibleEntityFactory {

    public:

    // EntityMaker is a function pointer type

    void Register( EntityType type, EntityMaker maker );

    void Unregister( EntityType type );

    IEntity* Create( EntityType type );// Actual factory fn

    private:

    // Store hash map from entity types (key) to maker

    // functions to implement the above functions

    };


Simple extensible factory usage

Simple Extensible Factory Usage

  • Define some types IDs:

    enum EntityTypes { ShipType, PlanetType };

  • Define “maker” functions for our types…

    IEntity* ShipMaker() {return new CShipEntity; }

    IEntity* PlanetMaker() { return new CPlanetEntity; }

  • Create our factory class and register our types

    ExtensibleFactory EntityFactory;

    EntityFactory.Register( ShipType, ShipMaker );

    EntityFactory.Register( PlanetType, PlanetMaker );

  • Now create objects as usual

    IEntity* ship1 = EntityFactory.Create( ShipType );


Issues with simple approach

Issues with Simple Approach

  • In this form we get little benefit over the original basic factory function

    • We must manually define a new type ID for each class

    • And hand code a “maker” function for each

    • Problems with coupling still present

  • We can generalise type IDs and maker functions

    • Use a class specific value instead of an enum for IDs

      • Static class member (UID or string) or perhaps use RTTI

    • Use a template to define a generic maker function

      • Assume maker functions all have same prototype


Extensible factory usage

Extensible Factory Usage

  • ID defined in the class:

    class CShipEntity{ static string ID = “ShipType”; ... }

  • All possible maker functions defined by a single template:

    template <class EntityType>

    IEntity* EntityMaker() { return new EntityType; }

  • Create our factory class and register our types

    ExtensibleFactory EntityFactory;

    EntityFactory.Register( EntityMaker<CShipEntity> );

  • This is simplified for brevity - see Rabin for further details and an implementation


Extensible factory usage1

Extensible Factory Usage

  • Extensible factories are advanced, but allow for much more flexible entity set-up

    • Simplify script-based set-up

    • Allow DLL usage (dynamic link library) - program add-ons can be created after the program is complete

  • Extensible factories can be used in other areas

    • An extensible resource factory is a very good idea

    • Allows for greater flexibility in the types of data file used

    • Again allowing for new data file types to be used without the need to recompile the core engine


  • Login