Creating an inherited class from ITimer?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Creating an inherited class from ITimer?

Post by pandoragami »

Hello all,

This question is more a programming question regarding virtuals and inheriting from the ITimer class. Basically I already know that I can use the device to get the Itimer (e.g. device->getTimer()) but what I would like to understand is how to inherit from the ITimer class directly like this.

Code: Select all

class timing: virtual public ITimer
{
    private:
 
    public:
 
    timing(){}
    ~timing(){}
    virtual ITimer* getTimer() = 0;
};
I did look at the code for the IrrlichtDevice.h to figure out how the device retrieves the timer but I get the error for the following code?

Code: Select all

 
C:\irrlicht_timer.cpp||In function 'int main()':|
C:\irrlicht_timer.cpp|92|error: cannot declare variable 'time' to be of abstract type 'timing'|
C:\irrlicht_timer.cpp|74|note:   because the following virtual functions are pure within 'timing':|
C:\irrlicht-1.7.2\include\ITimer.h|26|note:     virtual irr::u32 irr::ITimer::getRealTime() const|
C:\irrlicht-1.7.2\include\ITimer.h|33|note:     virtual irr::u32 irr::ITimer::getTime() const|
C:\irrlicht-1.7.2\include\ITimer.h|36|note:     virtual void irr::ITimer::setTime(irr::u32)|
C:\irrlicht-1.7.2\include\ITimer.h|42|note:     virtual void irr::ITimer::stop()|
C:\irrlicht-1.7.2\include\ITimer.h|48|note:     virtual void irr::ITimer::start()|
C:\irrlicht-1.7.2\include\ITimer.h|53|note:     virtual void irr::ITimer::setSpeed(irr::f32)|
C:\irrlicht-1.7.2\include\ITimer.h|58|note:     virtual irr::f32 irr::ITimer::getSpeed() const|
C:\irrlicht-1.7.2\include\ITimer.h|61|note:     virtual bool irr::ITimer::isStopped() const|
C:\irrlicht-1.7.2\include\ITimer.h|67|note:     virtual void irr::ITimer::tick()|
C:\irrlicht_timer.cpp|81|note:  virtual irr::ITimer* timing::getTimer()|

Here's the code

Code: Select all

 
#include <irrlicht.h>
#include <iostream>
 
using namespace irr;
 
class MyEventReceiver : public IEventReceiver
{
public:
 
    struct SMouseState
    {
        core::position2di Position;
        bool LeftButtonDown;
        SMouseState() : LeftButtonDown(false) { }
    } MouseState;
 
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
        if(event.EventType == EET_MOUSE_INPUT_EVENT)
        {
            switch(event.MouseInput.Event)
            {
            case EMIE_LMOUSE_PRESSED_DOWN:
                MouseState.LeftButtonDown = true;
                break;
 
            case EMIE_LMOUSE_LEFT_UP:
                MouseState.LeftButtonDown = false;
                break;
 
            case EMIE_MOUSE_MOVED:
                MouseState.Position.X = event.MouseInput.X;
                MouseState.Position.Y = event.MouseInput.Y;
                break;
 
            default:
 
                break;
            }
        }
 
        return false;
    }
 
    // This is used to check whether a key is being held down
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
 
    const SMouseState & GetMouseState(void) const
    {
        return MouseState;
    }
 
    MyEventReceiver()
    {
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }
 
private:
    // We use this array to store the current state of each key
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
 
class timing: virtual public ITimer
{
    private:
 
    public:
 
    timing(){}
    ~timing(){}
    virtual ITimer* getTimer() = 0;
};
 
 
MyEventReceiver receiver;
IrrlichtDevice* device = 0;
const int SCRX = 640;
const int SCRY = 480;
 
int main()
{
    timing time;
 
    device = createDevice( irr::video::EDT_OPENGL, core::dimension2d<u32>( SCRX, SCRY), 16, false, false, false, &receiver);
 
    if (device == 0)
        return 1;
 
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    gui::ICursorControl * cursor = device->getCursorControl();
 
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
    cursor->setVisible(false);
 
    int lastFPS = -1;
 
    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, true, video::SColor( 255, 0, 0, 0));
        smgr->drawAll();
        driver->endScene();
 
        int fps = driver->getFPS();
 
        if (lastFPS != fps)
        {
            core::stringw str = L"Irrlicht Text Node [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;
 
            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
 
    device->drop();
 
    return 0;
}
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Creating an inherited class from ITimer?

Post by CuteAlien »

Well, it's pretty much exactly what the error message says. It cannot cannot declare the variable 'time' of the class 'timing' because that is an abstract type. And timing is an abstract because a lot of virtual fuctions in timing are pure. It then goes on to list all function for which that is the case.
A function being pure means it looks like:

Code: Select all

 
class X
{
    virtual void MyFunction() = 0; // the = 0 makes it pure.
};
 
The idea behind pure functions is that it tells anyone who derives from such a class that this is pure interface and has no implementation. Which means you have to add an implementation.

So much for the theory. But you likely don't need that. You can't pass a timer back to Irrlicht so deriving from that is probably useless. If you need a timer then either write your own class - or use the a pointer to the Irrlicht timer in your class (here's an example where I do that: http://www.michaelzeilfelder.de/irrlicht.htm#Timer).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Creating an inherited class from ITimer?

Post by pandoragami »

CuteAlien wrote:
So much for the theory. But you likely don't need that. You can't pass a timer back to Irrlicht so deriving from that is probably useless. If you need a timer then either write your own class - or use the a pointer to the Irrlicht timer in your class (here's an example where I do that: http://www.michaelzeilfelder.de/irrlicht.htm#Timer).

Looking at that code for the timer it looks just like the ITimer class inside Irrlicht; I guess I'm supposed to initialize it with the ITimer here

Code: Select all

Timer(irr::ITimer * irrlichtTimer_, bool startRunning_=false);  
By passing the returned pointer from the device?

Code: Select all

device->getTimer();
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Creating an inherited class from ITimer?

Post by CuteAlien »

Yeah, it looks similar to ITimer as it's basically a wrapper around it. And yes - that's the pointer you pass.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Creating an inherited class from ITimer?

Post by pandoragami »

CuteAlien wrote:Yeah, it looks similar to ITimer as it's basically a wrapper around it. And yes - that's the pointer you pass.
But isn't that the same instance of the ITimer which implies that you would still have one timer for each Irrlicht device?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Creating an inherited class from ITimer?

Post by CuteAlien »

I only use it to get the time. Time is time... short of creating another universe I can't do much about that :-) The difference it that this one can be started/stopped independent of each other.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Creating an inherited class from ITimer?

Post by pandoragami »

CuteAlien wrote:I only use it to get the time. Time is time... short of creating another universe I can't do much about that :-) The difference it that this one can be started/stopped independent of each other.
But if you have only a single instance of ITimer and used one of the methods in the Timer wrapper you can only change that single ITimer object. Using start/stop would still only access the instance of that single ITimer object even if you have a hundred different wrappers e.g.

Code: Select all

Timer* instances[100];
Wouldn't an array of Timers only end up having the same functionality as a single device->getTimer pointer?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Creating an inherited class from ITimer?

Post by CuteAlien »

It's about virtual timers. The absolute time for all is the same, but this is not what this is about. This kind of time only updates on tick() (unless it's paused) - and it updates by a certain speed. The real time (aka ITimer) is only needed to compare to the time since the last tick() call. Take a look at the code - it's not that large.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply