inital PyCallable work; isolate very well behaved usage of PyObject references behind RAII
This commit is contained in:
parent
8739da8463
commit
972768eb26
|
@ -75,7 +75,7 @@ void GameEngine::manageTimer(std::string name, PyObject* target, int interval)
|
||||||
{
|
{
|
||||||
if (target == NULL || target == Py_None) // delete
|
if (target == NULL || target == Py_None) // delete
|
||||||
{
|
{
|
||||||
Py_DECREF(timers[name].target);
|
//Py_DECREF(timers[name].target);
|
||||||
timers.erase(it);
|
timers.erase(it);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ void GameEngine::manageTimer(std::string name, PyObject* target, int interval)
|
||||||
std::cout << "Refusing to initialize timer to None. It's not an error, it's just pointless." << std::endl;
|
std::cout << "Refusing to initialize timer to None. It's not an error, it's just pointless." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timers[name] = Timer(target, interval, runtime.getElapsedTime().asMilliseconds());
|
timers[name] = std::make_shared<PyTimerCallable>(target, interval, runtime.getElapsedTime().asMilliseconds());
|
||||||
Py_INCREF(target);
|
Py_INCREF(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void GameEngine::testTimers()
|
||||||
int now = runtime.getElapsedTime().asMilliseconds();
|
int now = runtime.getElapsedTime().asMilliseconds();
|
||||||
for (auto& [name, timer]: timers)
|
for (auto& [name, timer]: timers)
|
||||||
{
|
{
|
||||||
timer.test(now);
|
timer->test(now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "McRFPy_API.h"
|
#include "McRFPy_API.h"
|
||||||
#include "IndexTexture.h"
|
#include "IndexTexture.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "PyCallable.h"
|
||||||
|
|
||||||
class GameEngine
|
class GameEngine
|
||||||
{
|
{
|
||||||
|
@ -20,7 +21,8 @@ class GameEngine
|
||||||
std::string window_title;
|
std::string window_title;
|
||||||
|
|
||||||
sf::Clock runtime;
|
sf::Clock runtime;
|
||||||
std::map<std::string, Timer> timers;
|
//std::map<std::string, Timer> timers;
|
||||||
|
std::map<std::string, std::shared_ptr<PyTimerCallable>> timers;
|
||||||
void testTimers();
|
void testTimers();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -12,12 +12,6 @@ private:
|
||||||
texture_width = 12, texture_height = 11, // w & h sprite/frame count
|
texture_width = 12, texture_height = 11, // w & h sprite/frame count
|
||||||
texture_sprite_count = 11 * 12; // t_width * t_height, minus blanks?
|
texture_sprite_count = 11 * 12; // t_width * t_height, minus blanks?
|
||||||
|
|
||||||
// TODO: this is wrong, load resources @ GameEngineSprite sprite;
|
|
||||||
// sf::Texture texture;
|
|
||||||
|
|
||||||
//std::vector<PyMethodDef> mcrfpyMethodsVector;
|
|
||||||
//static PyObject* PyInit_mcrfpy();
|
|
||||||
|
|
||||||
McRFPy_API();
|
McRFPy_API();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "PyCallable.h"
|
||||||
|
|
||||||
|
PyCallable::PyCallable(PyObject* _target)
|
||||||
|
{
|
||||||
|
target = Py_XNewRef(_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyCallable::~PyCallable()
|
||||||
|
{
|
||||||
|
if (target)
|
||||||
|
Py_DECREF(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* PyCallable::call(PyObject* args, PyObject* kwargs)
|
||||||
|
{
|
||||||
|
return PyObject_Call(target, args, kwargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTimerCallable::PyTimerCallable(PyObject* _target, int _interval, int now)
|
||||||
|
: PyCallable(_target), interval(_interval), last_ran(now)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PyTimerCallable::PyTimerCallable()
|
||||||
|
: PyCallable(Py_None), interval(0), last_ran(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool PyTimerCallable::hasElapsed(int now)
|
||||||
|
{
|
||||||
|
return now >= last_ran + interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PyTimerCallable::call(int now)
|
||||||
|
{
|
||||||
|
PyObject* args = Py_BuildValue("(i)", now);
|
||||||
|
PyObject* retval = PyCallable::call(args, NULL);
|
||||||
|
if (!retval)
|
||||||
|
{
|
||||||
|
std::cout << "timer has raised an exception. It's going to STDERR and being dropped:" << std::endl;
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
} else if (retval != Py_None)
|
||||||
|
{
|
||||||
|
std::cout << "timer returned a non-None value. It's not an error, it's just not being saved or used." << std::endl;
|
||||||
|
std::cout << PyUnicode_AsUTF8(PyObject_Repr(retval)) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PyTimerCallable::test(int now)
|
||||||
|
{
|
||||||
|
if(hasElapsed(now))
|
||||||
|
{
|
||||||
|
call(now);
|
||||||
|
last_ran = now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Python.h"
|
||||||
|
|
||||||
|
class PyCallable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
PyObject* target;
|
||||||
|
protected:
|
||||||
|
PyCallable(PyObject*);
|
||||||
|
~PyCallable();
|
||||||
|
PyObject* call(PyObject*, PyObject*);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyTimerCallable: public PyCallable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int interval;
|
||||||
|
int last_ran;
|
||||||
|
void call(int);
|
||||||
|
public:
|
||||||
|
bool hasElapsed(int);
|
||||||
|
bool test(int);
|
||||||
|
PyTimerCallable(PyObject*, int, int);
|
||||||
|
PyTimerCallable();
|
||||||
|
};
|
Loading…
Reference in New Issue