quick & dirty timer functionality
This commit is contained in:
		
							parent
							
								
									9d728ee902
								
							
						
					
					
						commit
						ccd79fc551
					
				| 
						 | 
					@ -37,6 +37,7 @@ GameEngine::GameEngine()
 | 
				
			||||||
    IndexSprite::game = this;
 | 
					    IndexSprite::game = this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    clock.restart();
 | 
					    clock.restart();
 | 
				
			||||||
 | 
					    runtime.restart();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Scene* GameEngine::currentScene() { return scenes[scene]; }
 | 
					Scene* GameEngine::currentScene() { return scenes[scene]; }
 | 
				
			||||||
| 
						 | 
					@ -55,6 +56,7 @@ void GameEngine::run()
 | 
				
			||||||
    while (running)
 | 
					    while (running)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        currentScene()->update();
 | 
					        currentScene()->update();
 | 
				
			||||||
 | 
					        testTimers();
 | 
				
			||||||
        sUserInput();
 | 
					        sUserInput();
 | 
				
			||||||
        if (!paused)
 | 
					        if (!paused)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -67,6 +69,36 @@ void GameEngine::run()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GameEngine::manageTimer(std::string name, PyObject* target, int interval)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //std::cout << "Manage timer called. " << name << " " << interval << std::endl;
 | 
				
			||||||
 | 
					    if (timers.find(name) != timers.end()) // overwrite existing
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (target == NULL || target == Py_None) // delete
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Py_DECREF(target);
 | 
				
			||||||
 | 
					            timers.erase(name);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (target == NULL || target == Py_None)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cout << "Refusing to initialize timer to None. It's not an error, it's just pointless." << std::endl;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    timers[name] = Timer(target, interval, runtime.getElapsedTime().asMilliseconds());
 | 
				
			||||||
 | 
					    Py_INCREF(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GameEngine::testTimers()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int now = runtime.getElapsedTime().asMilliseconds();
 | 
				
			||||||
 | 
					    for (auto& [name, timer]: timers)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        timer.test(now);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GameEngine::sUserInput()
 | 
					void GameEngine::sUserInput()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    sf::Event event;
 | 
					    sf::Event event;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
#include "Scene.h"
 | 
					#include "Scene.h"
 | 
				
			||||||
#include "McRFPy_API.h"
 | 
					#include "McRFPy_API.h"
 | 
				
			||||||
#include "IndexTexture.h"
 | 
					#include "IndexTexture.h"
 | 
				
			||||||
 | 
					#include "Timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GameEngine
 | 
					class GameEngine
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -20,6 +21,10 @@ class GameEngine
 | 
				
			||||||
    float frameTime;
 | 
					    float frameTime;
 | 
				
			||||||
    std::string window_title;
 | 
					    std::string window_title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sf::Clock runtime;
 | 
				
			||||||
 | 
					    std::map<std::string, Timer> timers;
 | 
				
			||||||
 | 
					    void testTimers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    std::string scene;
 | 
					    std::string scene;
 | 
				
			||||||
    GameEngine();
 | 
					    GameEngine();
 | 
				
			||||||
| 
						 | 
					@ -35,6 +40,7 @@ public:
 | 
				
			||||||
    int getFrame() { return currentFrame; }
 | 
					    int getFrame() { return currentFrame; }
 | 
				
			||||||
    float getFrameTime() { return frameTime; }
 | 
					    float getFrameTime() { return frameTime; }
 | 
				
			||||||
    sf::View getView() { return visible; }
 | 
					    sf::View getView() { return visible; }
 | 
				
			||||||
 | 
					    void manageTimer(std::string, PyObject*, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // global textures for scripts to access
 | 
					    // global textures for scripts to access
 | 
				
			||||||
    std::vector<IndexTexture> textures;
 | 
					    std::vector<IndexTexture> textures;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,9 @@ static PyMethodDef mcrfpyMethods[] = {
 | 
				
			||||||
    {"createScene", McRFPy_API::_createScene, METH_VARARGS, "createScene(scene) - create a new blank scene with given name"},
 | 
					    {"createScene", McRFPy_API::_createScene, METH_VARARGS, "createScene(scene) - create a new blank scene with given name"},
 | 
				
			||||||
    {"keypressScene", McRFPy_API::_keypressScene, METH_VARARGS, "keypressScene(callable) - assign a callable object to the current scene receive keypress events"},
 | 
					    {"keypressScene", McRFPy_API::_keypressScene, METH_VARARGS, "keypressScene(callable) - assign a callable object to the current scene receive keypress events"},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {"setTimer", McRFPy_API::_setTimer, METH_VARARGS, "setTimer(name:str, callable:object, interval:int) - callable will be called with args (runtime:float) every `interval` milliseconds"},
 | 
				
			||||||
 | 
					    {"delTimer", McRFPy_API::_delTimer, METH_VARARGS, "delTimer(name:str) - stop calling the timer labelled with `name`"},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {NULL, NULL, 0, NULL}
 | 
					    {NULL, NULL, 0, NULL}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -450,3 +453,21 @@ PyObject* McRFPy_API::_keypressScene(PyObject* self, PyObject* args) {
 | 
				
			||||||
    Py_INCREF(Py_None);
 | 
					    Py_INCREF(Py_None);
 | 
				
			||||||
    return Py_None;		
 | 
					    return Py_None;		
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject* McRFPy_API::_setTimer(PyObject* self, PyObject* args) { // TODO - compare with UIDrawable mouse & Scene Keyboard methods - inconsistent responsibility for incref/decref around mcrogueface
 | 
				
			||||||
 | 
					    const char* name;
 | 
				
			||||||
 | 
					    PyObject* callable;
 | 
				
			||||||
 | 
					    int interval;
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "sOi", &name, &callable, &interval)) return NULL;
 | 
				
			||||||
 | 
					    game->manageTimer(name, callable, interval);
 | 
				
			||||||
 | 
					    Py_INCREF(Py_None);
 | 
				
			||||||
 | 
					    return Py_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject* McRFPy_API::_delTimer(PyObject* self, PyObject* args) {
 | 
				
			||||||
 | 
						const char* name;
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "s", &name)) return NULL;
 | 
				
			||||||
 | 
					    game->manageTimer(name, NULL, 0);
 | 
				
			||||||
 | 
					    Py_INCREF(Py_None);
 | 
				
			||||||
 | 
					    return Py_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,11 @@ public:
 | 
				
			||||||
    static PyObject* _currentScene(PyObject*, PyObject*);
 | 
					    static PyObject* _currentScene(PyObject*, PyObject*);
 | 
				
			||||||
    static PyObject* _createScene(PyObject*, PyObject*);
 | 
					    static PyObject* _createScene(PyObject*, PyObject*);
 | 
				
			||||||
    static PyObject* _keypressScene(PyObject*, PyObject*); 
 | 
					    static PyObject* _keypressScene(PyObject*, PyObject*); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // timer control
 | 
				
			||||||
 | 
					    static PyObject* _setTimer(PyObject*, PyObject*);
 | 
				
			||||||
 | 
					    static PyObject* _delTimer(PyObject*, PyObject*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // accept keyboard input from scene
 | 
					    // accept keyboard input from scene
 | 
				
			||||||
    static sf::Vector2i cursor_position;
 | 
					    static sf::Vector2i cursor_position;
 | 
				
			||||||
    static void player_input(int, int);
 | 
					    static void player_input(int, int);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					#include "Timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timer::Timer(PyObject* _target, int _interval, int now)
 | 
				
			||||||
 | 
					: target(_target), interval(_interval), last_ran(now)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //Py_INCREF(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timer::Timer()
 | 
				
			||||||
 | 
					: target(Py_None), interval(0), last_ran(0)
 | 
				
			||||||
 | 
					{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timer::Timer(Timer& other)
 | 
				
			||||||
 | 
					: target(other.target), interval(other.interval), last_ran(other.last_ran)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //Py_INCREF(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timer::~Timer()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //if (target && target != Py_None)
 | 
				
			||||||
 | 
					    //    Py_DECREF(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Timer::test(int now)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!target || target == Py_None) return false;
 | 
				
			||||||
 | 
					    if (now > last_ran + interval)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        last_ran = now;
 | 
				
			||||||
 | 
					        PyObject* args = Py_BuildValue("(i)", now);
 | 
				
			||||||
 | 
					        std::cout << PyUnicode_AsUTF8(PyObject_Repr(args)) << std::endl;
 | 
				
			||||||
 | 
					        PyObject_Call(target, args, NULL);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "Common.h"
 | 
				
			||||||
 | 
					#include "Python.h"
 | 
				
			||||||
 | 
					class GameEngine; // forward declare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Timer
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    PyObject* target;
 | 
				
			||||||
 | 
					    int interval;
 | 
				
			||||||
 | 
					    int last_ran;
 | 
				
			||||||
 | 
					    Timer(); // for map to build
 | 
				
			||||||
 | 
					    Timer(Timer& other); // copy constructor
 | 
				
			||||||
 | 
					    Timer(PyObject*, int, int);
 | 
				
			||||||
 | 
					    ~Timer();
 | 
				
			||||||
 | 
					    bool test(int);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
		Reference in New Issue