Thread: I believe I've found an official Answer to my Problem (Object Factories)

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    And to answer the questions of monster problems.

    This would be much better:

    Code:
    enum Modes  
    {
      SET_X=0x01,
      SET_Y=0x02,
      SET_HEALTH=0x04;
      SET_STAMINA=0x08;
    };
    
    
    struct MonsterAttributes
    {
      int iPosx;
      int iPosy;
      int iHealth;
      int iStamina;
     
    };
    
    class Monster
    {
      DWORD m_dwID;
      MonsterAttributes MonsterInfo;
    
      Monster(void);
      Monster(const MonsterAttributes m);
      Monster(const Monster &m);
      virtual ~Monster(void);
      
      void SetInfo(int mode,int value)
      {
       if ((mode & Modes::SET_X)==Modes::SET_X)
       {
         MonsterInfo.iPosx=value;
       }
    
       ...
       ...
      }
     }
    };
    
    class MonsterContainer
    {
      std::vector<Monster *>  Monsters;
    
      //Cannot copy monster container
      MonsterContainer(const MonsterContainer &m) {}
      MonsterContainer &operator (const MonsterContainer &m) {}
    
      public:
        virtual ~MonsterContainer(void)
        {
           for (int i=0;i<Monsters.size();i++)
           {
              //MSVC 6 bug
              if (Monsters[i])
              {
                 delete Monsters[i];
              }
           }
    
        }
        DWORD Add(MonsterAttributes &attr)
        {
           Monster *m=new Monster(attr);
           Monsters.push_back(&m);
           return Monsters.size()-1;
        }
      
        bool Remove(DWORD dwID);
        void Update(void);
        ...
    
    };
    There really is no need to derive from Monster.
    Last edited by VirtualAce; 12-19-2005 at 07:10 AM.

  2. #2
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Ohhh I see now. The containers do their own thing with the IDs, but the IDs match up to the ID returned from your monster container?

    What I thought was going on was you had an Object Container and were using that to get your object instances based on ID and then worked with those (originally I assumed a map). So what do you do if you want to add extra functionality to a Monster? For instance FireBall(), when not all Monsters should have that method? Just add every method to Monster? Or add some scripting/retrieve from file system that CornedBee was talking about and Diablo?

    That makes a lot more sense now at least. I was trying to get some psuedo c++ code (obviously bubbeudo), but I found if I was retrieving Object's from an ObjectSystem then there would be no use for a functor (because I could just call it from the object), therefor a map (in MessageSystem) either, so that didn't match up with what you were saying.

    Would inheriting from MessageSystem solve the problem to have them use the default handler unless defined? might be kind of illogical though.

    This is some of the bubbeudo I got from your posts, without all the bells and whistles, in order to try and grasp the message system (I think I failed):

    Code:
    #include <iostream>
    #include <vector>
    
    #include "windows.h"
    
    struct ObjectInfo;
    class Object;
    class ObjectContainer;
    class Message;
    class MessageSystem;
    
    class Message
    {
    public:
        std::vector<DWORD> ObjectIDs;
        std::vector<DWORD> CommandIDs;
    };
    
    struct ObjectInfo
    {
        DWORD dwStartIndex;
        DWORD dwEndIndex;
        DWORD dwID;
        DWORD *dwTextureIDs;
    };
    
    class Object
    {
    private:
        ObjectInfo ObjectData;
    
    public:
        //queue and such here
    
        void RecieveMessage(Message* p_Message)
        {
            HandleMessage(p_Message);
        }
    
        //enum commands { FIRE, ICE, LIGHTNING }
    
        void HandleMessage(Message* p_Message)
        {
            //handle all commands in the message
            for(int i = 0; i < p_Message->CommandIDs.size(); ++i) {
                switch(p_Message->CommandIDs[i]) {
                    case 1: Fire(p_Message->ObjectIDs[i]);
                    break;
                    case 2: Ice(p_Message->ObjectIDs[i]);
                    break;
                    case 3: Lightning(p_Message->ObjectIDs[i]);
                    break;
                }
            }
        }
    
        void Fire(DWORD dwID) { std::cout << "Fire! on " << dwID << std::endl; }
        void Ice(DWORD dwID) { std::cout << "Ice! on " << dwID << std::endl; }
        void Lightning(DWORD dwID) { std::cout << "Lightning! on " << dwID << std::endl; }
    
        DWORD GetID(void) { return ObjectData.dwID; }
        void SetID(DWORD dwID) { ObjectData.dwID = dwID; }
    };
    
    class ObjectContainer
    {
        std::vector<Object*> m_Objects;
    
        static ObjectContainer* m_Instance;
    
    public:
        Object* GetObject(DWORD dwID)
        {
            return m_Objects[dwID];
        }
    
        DWORD Add(void)
        {
            Object* Obj = new Object();
            Obj->SetID(m_Objects.size()-1);
            m_Objects.push_back(Obj);
    
            return m_Objects.size()-1;
        }
    
        bool Remove(DWORD dwID)
        {
            delete m_Objects[dwID];
        }
    
        static ObjectContainer* Instance(void)
        {
            if(!m_Instance) {
                m_Instance = new ObjectContainer;
            }
    
            return m_Instance;
        }
    };
    
    ObjectContainer* ObjectContainer::m_Instance = 0;
    
    class MessageSystem
    {
    private:
        //std::vector<DWORD> m_Registered;
        static MessageSystem* m_Instance;
    
    public:
        void RegisterObject(DWORD dwID)
        {
            //
        }
    
        void SendMessageToObject(Message* p_Message, DWORD dwID)
        {
            ObjectContainer::Instance()->GetObject(dwID)->RecieveMessage(p_Message);
        }
    
        //enum commands { DIE, STUFF }
    
        void HandleMessage(Message* p_Message)
        {
            for(int i = 0; i < p_Message->CommandIDs.size(); ++i) {
                switch(p_Message->CommandIDs[i]) {
                    case 1: //Defualt1();
                    break;
                    case 2: //Defualt2();
                    break;
                }
            }
        }
    
        static MessageSystem* Instance()
        {
            if(!m_Instance) {
                m_Instance = new MessageSystem;
            }
    
            return m_Instance;
        }
    };
    
    MessageSystem* MessageSystem::m_Instance = 0;
    
    int main()
    {
        ObjectContainer* ObjCon = ObjectContainer::Instance();
        MessageSystem* MsgSys = MessageSystem::Instance();
    
        DWORD Obj = ObjCon->Add();
    
        //MsdSys->RegisterObject(Obj);
    
        Message* Msg = new Message;
        Msg->CommandIDs.push_back(3); //Lightning Command 3
        Msg->ObjectIDs.push_back(2); //Use Command on Object 2
        Msg->CommandIDs.push_back(1); //Fire Command 1
        Msg->ObjectIDs.push_back(4); //Use Command on Object 4
    
        MsgSys->SendMessageToObject(Msg, Obj);
    
        std::cin.get();
    }
    As you can see, HandleMessage() has a switch, and thats the only way I could visualize it. Maybe its the handler that I'm ultimately unclear on. Like if you're recieving messages that use command IDs like FIRE_BALL, then wouldn't you HAVE to use a switch to resolve the function. And if you did derive from Object in my example, then you would have to make it virtual and overwrite it in the derived so it could call its new methods. See why I'm so confused? lol.

    Anyway, feel free to give up on me whenever - I won't mind. I'm having a hard time understanding because my experience with game programming is: few days; my experience in c++ is: 6 months (include vacation/school/learning flash/java).

    EDIT: Updated the bubbeudo a bit based on your last posts before I go out.

    EDIT: I'll reread all your posts and see if I can impliment some stuff and hopefully understand whats going on.
    Last edited by Dae; 12-19-2005 at 04:00 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  3. #3
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Would inheriting from MessageSystem solve the problem to have them use the default handler unless defined? might be kind of illogical though.
    Scratch that. It's really stupid and illogical to do that for every class just to use the default handler. Lemme know if you figure out a way without macro magic.

    but I found if I was retrieving Object's from an ObjectSystem then there would be no use for a functor
    Scratch that. I see why the functor was necessary, since it might not always be Object's you're working with. I just missed that because you went off talking about Object's.


    I'm still unclear on the handler using a switch or not, and how to pass MSG_FIRE instead of a number - that require either a macro, global const, or global enum?

    EDIT: I guess if the message system was that robust there would be a global enum or enum in the handler class or something.

    EDIT: Found a nice powerpoint on scripting: http://www.cmpevents.com/sessions/GD...sy_UPDATED.ppt

    Use script handlers
    - For flexibility and prototyping
    - To avoid C++ dependencies
    - Reduce C++ subclasses

    Use C++ handlers
    - For special arg handling
    - Performance, maintainance
    It answered my question on how to handle a special amount of arguments and a few other things. Still though, I have a lot to learn before I can impliment this message system or scripting system.
    Last edited by Dae; 12-21-2005 at 05:24 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. using this as synchronization object
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 03-22-2008, 07:49 AM
  2. problem with answer going to default?
    By Patrick1234 in forum C++ Programming
    Replies: 4
    Last Post: 10-02-2002, 09:11 AM
  3. slight problem just can't see the answer
    By anthonye in forum C++ Programming
    Replies: 1
    Last Post: 07-05-2002, 08:45 AM
  4. I've ran into a problem
    By Mike Jones in forum C Programming
    Replies: 1
    Last Post: 03-27-2002, 04:08 PM
  5. code help :)
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 02-28-2002, 01:12 PM