Aktuelle Zeit: 15.08.2020, 09:44

Alle Zeiten sind UTC + 1 Stunde




Ein neues Thema erstellen Auf das Thema antworten  [ 2 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Singelton Template
BeitragVerfasst: 18.06.2009, 01:03 
Offline

Registriert: 12.04.2007, 11:47
Beiträge: 108
Ok mir war langweilig und ich hab ein SingeltonTemplate geschrieben mit dem man aus jede Klasse oder Variable ein Singleton machen kann ohne diese zu verändern. Man könnte sogar das IrrlichtDevice zu einem ingelton machen
Das Template:
Code:
#include <iostream>
#include <irrlicht.h>
#include <assert.h>

template<class A>
class SingeltonTemplate
{
public:
    SingeltonTemplate(A* i = NULL)
    {
        if (RefCounter == 0)
        {
            Instance = i;
        }
        //if (Instance == NULL) //try calling standard constructor...not a good idea
        //Instance = new A();
        assert(Instance != NULL);
        if (AutoRemove)
            RefCounter++;
    }
    SingeltonTemplate(const SingeltonTemplate<A>& singelton)
    {
        if (Instance == NULL) //try calling standard constructor
            Instance = new A();
        assert(Instance != NULL);
        if (AutoRemove)
            RefCounter++;
    }
    ~SingeltonTemplate(void)
    {
        if (AutoRemove && Instance)
            RefCounter--;
        if (RefCounter == 0)
        {
            delete Instance;
            Instance = NULL;
        }
        assert(RefCounter >= 0);
    }
    A* operator->(void)
    {
        return Instance;
    }
    A* operator*(void)
    {
        return Instance;
    }
    const A* operator->(void) const
    {
        return Instance;
    }
    const A* operator*(void) const
    {
        return Instance;
    }
    static void TurnAutoRemoveOff(void)
    {
        AutoRemove = false;
    }
    void Destroy(void)
    {
        AutoRemove = true;

        if (Instance)
            delete Instance;

        Instance = NULL;

        RefCounter = 0;
    }
    const bool Valid(void) const
    {
        if ((RefCounter > 0 || !AutoRemove) && Instance)
            return true;
        return false;
    }
    static int GetRefCount(void)
    {
        return RefCounter;
    }


    SingeltonTemplate& operator=(const SingeltonTemplate<A>& singelton)
    {
        //dunno but i think i don't have to grab the pointer here
    }
protected:
    static A* Instance;
    static int RefCounter;
    static bool AutoRemove;
};
template<class A> A* SingeltonTemplate<A>::Instance = NULL;
template<class A> int SingeltonTemplate<A>::RefCounter = 0;
template<class A> bool SingeltonTemplate<A>::AutoRemove = true;


Und hier ein Beispiel. Ich weiß das ich da c und c++ dinge vermische und es eigentlich keinen sinn macht aber das hier ist auch ein beispiel für das singelton und nicht zum lernen von designs gedacht.

Code:
class CEntity;
typedef void (*UpdatePointer)(int timeMs, CEntity& entity);
typedef void (*InitPointer)(CEntity& entity);
typedef void (*TimeEventPointer)(void);

void StandardEntityUpdate(int timeMs, CEntity& entity);

class CEntityData
{
public:
    virtual ~CEntityData(void)
    {
    }
};

class CEntity
{
public:
    CEntity(int id, const irr::c8* type) : EntityID(id), EntityType(type), UpdateEntity(&StandardEntityUpdate), Data(NULL)
    {
    }
    CEntity(const CEntity& entity) : EntityID(entity.getEntityID()), EntityType(entity.EntityType), UpdateEntity(entity.UpdateEntity), Data(NULL)
    {
    }
    CEntity& operator=(const CEntity& entity)
    {
        EntityID = entity.getEntityID();
        UpdateEntity = entity.UpdateEntity;
        Data = entity.Data;
        EntityType = entity.EntityType;
        return *this;
    }
    const int& getEntityID(void) const
    {
        return EntityID;
    }

    void setEntityData(CEntityData* data)
    {
        Data = data;
    }

    CEntityData* getEntityData(void)
    {
        return Data;
    }

    const CEntityData* getEntityData(void) const
    {
        return Data;
    }

    UpdatePointer UpdateEntity;
    InitPointer Destructor;
protected:
    int EntityID;
    CEntityData* Data;
    irr::core::stringc EntityType;
};

void StandardEntityUpdate(int timeMs, CEntity& entity)
{
    std::cout<<"Entity["<<entity.getEntityID()<<"] Time: "<<timeMs<<std::endl;
}

class CGameEngine
{
public:
    CGameEngine(void)
    {
        LastEntityID = 0;
        Device = irr::createDevice(irr::video::EDT_OPENGL);
    }

    ~CGameEngine(void)
    {
        Device->drop();
    }

    void RegisterInit(const irr::c8* name, InitPointer init, InitPointer desctruct)
    {
        for (int i=0;i<InitEntities.size();i++)
        {
            if (InitEntities[i].Name == name)
            {
                InitEntities[i].Init = init;
                return;
            }
        }
        InitEntities.push_back(EntityTemplate(name, init, desctruct));
    }

    int addEntity(const irr::c8* name = NULL)
    {
        std::cout<<"Added Entity"<<std::endl;
        Entities.push_back(CEntity(LastEntityID++, name));
        for (int i=0;i<InitEntities.size();i++)
        {
            if (InitEntities[i].Name == name)
            {
                InitEntities[i].Init(Entities[Entities.size()-1]);
                Entities[Entities.size()-1].Destructor = InitEntities[i].Destruct;
            }
        }
        return Entities[Entities.size()-1].getEntityID();
    }

    void removeEntity(int i)
    {
        if (Entities.size() > i)
        {
            Entities[i].Destructor(Entities[i]);
            Entities.erase(i);
        }
    }

    void addTimeEvent(int timeMs, TimeEventPointer event)
    {
        TimeEvents.push_back(TimeEvent(Device->getTimer()->getTime()+timeMs, event));
        TimeEvents.sort();
    }

    void Run(void)
    {
        while (Device->run())
        {
            //update entities
            for (int i=0;i<Entities.size();i++)
                Entities[i].UpdateEntity(Device->getTimer()->getTime(), Entities[i]);

            //trigger Events
            while(TimeEvents.size() > 0 && TimeEvents[0].TimeMs < Device->getTimer()->getTime())
            {
                TimeEvents[0].Event();
                TimeEvents.erase(0);
            }


            //Render stuff
            Device->getVideoDriver()->beginScene(true, true, irr::video::SColor(255,0,0,255));

            Device->getSceneManager()->drawAll();

            Device->getGUIEnvironment()->drawAll();

            Device->getVideoDriver()->endScene();
        }

        Device->closeDevice();
    }

    int getTime(void) const
    {
        return Device->getTimer()->getTime();
    }

    irr::IrrlichtDevice* getDevice(void)
    {
        return Device;
    }
protected:
    int LastEntityID;
    irr::core::array<CEntity> Entities;
    class TimeEvent
    {
    public:
        TimeEvent(int timeMs, TimeEventPointer event) : TimeMs(timeMs), Event(event)
        {
        }
        TimeEvent(const TimeEvent& tmp) : TimeMs(tmp.TimeMs), Event(tmp.Event)
        {
        }
        TimeEvent& operator=(const TimeEvent& tmp)
        {
            TimeMs = tmp.TimeMs;
            Event = tmp.Event;
            return *this;
        }
        bool operator<(const TimeEvent& tmp)
        {
            return TimeMs < tmp.TimeMs;
        }
        int TimeMs;
        TimeEventPointer Event;
    };
    class EntityTemplate
    {
    public:
        EntityTemplate(const irr::c8* name, InitPointer init, InitPointer destruct)
        {
            Name = name;
            Init = init;
            Destruct = destruct;
        }
        EntityTemplate(const EntityTemplate& temp)
        {
            Name = temp.Name;
            Init = temp.Init;
            Destruct = temp.Destruct;
        }
        EntityTemplate& operator=(const EntityTemplate& temp)
        {
            Name = temp.Name;
            Init = temp.Init;
            Destruct = temp.Destruct;
            return *this;
        }
        irr::core::stringc Name;
        InitPointer Init;
        InitPointer Destruct;
    };
    irr::core::array<EntityTemplate> InitEntities;
    irr::core::array<TimeEvent> TimeEvents;

    //irrlicht
    irr::IrrlichtDevice* Device;
};

typedef SingeltonTemplate<CGameEngine> GameEngine;

class CPlayerData : public CEntityData
{
public:
    CPlayerData(void)
    {
        Health = 0;
        Node = NULL;
        Cam = NULL;
    }
    ~CPlayerData(void)
    {
        if (Node)
        {
            Node->remove();
            Node->drop();
        }
        if (Cam)
        {
            Cam->remove();
            Cam->drop();
        }
        Node = NULL;
        Cam = NULL;
    }

    irr::scene::ISceneNode* Node;
    irr::scene::ICameraSceneNode* Cam;
    int Health;
};


void UpdatePlayer(int timeMs, CEntity& entity)
{
    std::cout<<"Update Player ["<<entity.getEntityID()<<"] Time: "<<timeMs<<std::endl;
}
void InitPlayer(CEntity& entity)
{
    std::cout<<"Init Player"<<std::endl;
    CPlayerData* data = new CPlayerData;
    entity.setEntityData(data);
    entity.UpdateEntity = &UpdatePlayer;

    //load mesh
    GameEngine engine;
    data->Node = engine->getDevice()->getSceneManager()->addAnimatedMeshSceneNode(engine->getDevice()->getSceneManager()->getMesh("faerie.md2"));
    data->Node->grab();
    data->Cam = engine->getDevice()->getSceneManager()->addCameraSceneNodeFPS();
    data->Cam->grab();
}
void DeInitPlayer(CEntity& entity)
{
    delete entity.getEntityData();
}

void RemovePlayerEvent(void)
{
    GameEngine engine;
    engine->removeEntity(0);
}

void TestEvent(void)
{
    GameEngine engine;
    std::cout<<"Test Event: "<<engine->getTime()<<std::endl;
}

int main(void)
{
    GameEngine engine(new CGameEngine);
    engine->addTimeEvent(10000, &RemovePlayerEvent);
    engine->addTimeEvent(500, &TestEvent);
    engine->RegisterInit("player", &InitPlayer, &DeInitPlayer);
    engine->addEntity("player");
    engine->Run();
    return 0;
}


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Singelton Template
BeitragVerfasst: 15.08.2009, 18:37 
Offline

Registriert: 16.01.2008, 12:31
Beiträge: 79
Geht aber auch kürzer. :)
http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)#Implementierung_in_C.2B.2B


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 2 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de