Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have started create a lightweight game engine with Ogre and C++. I have a abstract component class and an abstract entity class.

#ifndef ENTITY_HPP_
#define ENTITY_HPP_

#include <string>
#include <vector>

#include "Component.hpp"

class Entity
{
public:
    Entity(int uniqueId) { m_UniqueId = uniqueId; };
    ~Entity();

    void AddComponent(Component *comp);
    void RemoveComponent(Component *comp);

    Component *GetComponent(m_ComponentTypes type);

    int GetID() { return m_UniqueId; };
protected:
    std::vector<Component*> m_Components;
    int m_UniqueId;
};

#endif /* ENTITY_HPP_ */

Component:

/*
 * Component.hpp
 *
 *  Created on: Jul 15, 2013
 *      Author: dominik
 */

#ifndef COMPONENT_HPP_
#define COMPONENT_HPP_

#include <string>

class Entity;

typedef enum
{
    MESH_COMPONENT,
    POSITION_COMPONENT,
} m_ComponentTypes;

class Component
{
public:
    Component(m_ComponentTypes type) { m_Type = type; m_pParent = NULL; };
    virtual ~Component();

    void SetParent(Entity *entity) { m_pParent = entity; };
    Entity *GetParent() const { return m_pParent; };

    m_ComponentTypes GetType() const { return m_Type; };

protected:
    Entity *m_pParent;
    m_ComponentTypes m_Type;
};

#endif /* COMPONENT_HPP_ */

After this I created an EntityManager where I manage all entities in the game world, an a rendersystem where I render all entities and initialize Ogre. Now I have a window, but I need the escape button managed -> so I implement an inputsystem and here is the problem. My InputSystem works with OIS which needs a handle to the window, the handle to the window is available in the RenderSystem but not in the InputSystem, how can I get this data?

Here is my engine class:

/*
 * Engine.hpp
 *
 *  Created on: Jul 15, 2013
 *      Author: dominik
 */

#ifndef ENGINE_HPP_
#define ENGINE_HPP_

#include "EntityManager.hpp"
#include "RenderSystem.hpp"

#include <vector>

class Engine
{
public:
    static Engine *GetInstancePtr()
    {
        if (!instance)
            instance = new Engine();

        return instance;
    }

    EntityManager *m_pEntityManager;

    void update(double timeSinceLastFrame);
    void loop();

    void Shutdown() { m_bShutdown = true; };
private:
    static Engine *instance;

    Engine()
    {
        m_pEntityManager = new EntityManager();

        m_Systems.push_back(new RenderSystem());

        m_bShutdown = false;
    }
    Engine(const Engine&);

    ~Engine()
    {
        delete m_pEntityManager;

        while(!m_Systems.empty())
        {
            System *sys = m_Systems.back();
            delete sys;
            m_Systems.pop_back();
        }
    }

    std::vector<System*> m_Systems;

    bool m_bShutdown;
};

#endif /* CORE_HPP_ */

In my Engine singleton I have only the abstract system class, so I can't get the window handle. Is there a nice solution?

Any suggestions? Is my approach correct, or is it limitated in any way?

How should I implement the input manager, should he handle all the clicks on keyboard and mouse and send events, or should I create a component with the input manager fields and react on this in this entities which have this component added?

share|improve this question
add comment

2 Answers 2

up vote 3 down vote accepted

Input and windowing is just kind of a pain. You typically need to tightly integrate input, windowing, and the main loop, and cross up responsibilities to some degree.

One option is to just put a lot of core utility code and classes for input, windowing, and so on into a separate "platform" module (you can also put low-level I/O and threading routines here). Your engine can then just call into a PlatformPumpMessage, your input system can register a callback via a PlatformSetInputCallback(&input_handler), and so on.

Another option is to move everything into a subsystem of your engine, such as windowing.

Messaging of some kind is probably the most important part. In order for one system to know what's happening in another (like your InputSystem knowing what's happening in whatever handles the low-level input events), you need to have some way for the input system to subscribe to such events. A simple callback pointer works very well. A more complicated message/event layer is another possibility.

share|improve this answer
    
Yeah, that means I need a messaging system also for my subsystems. I think I have to implement one for the entities in every case. But for this I have to identify the subsystem, that means I need an enum or anything. What is a "good" way to identify my subsystems? –  Dominik2000 Jul 16 '13 at 6:49
    
Or just the function callback. You don't need a whole messaging system if you don't have any other uses for it. You also have no need to identify subsystem; store pointers (smart pointers) in your message receivers. –  Sean Middleditch Jul 16 '13 at 7:41
add comment

In my experience with Ogre, I follow Sean's advice and factor out all this logic into a separate platform-specific module or some application specific class/module rather than trying to tie it into the game engine itself.

For example, OIS is designed where you need to pass the external window handle to it for the input hooks to be properly hooked into the platform's main loop. Similarly, you can initialize Ogre where it doesn't create the window but instead you give it the external window handle to where it is to render. At that point, all Ogre does is hooks into the windowing API and renders to that handle when the RenderWindow object gets instantiated.

I personally prefer this approach rather than having Ogre create the render window. Now, depending on whether you're using the engine in a game client situation or embedded into an editor application, the rendering system interface and interaction should basically be the same. Plus, you can wire input/windowing however necessary based on the application's needs without extra method calls for either case within the engine.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.