Many hours of pain & research behind this small commit. Safe object building by not messing with types before interpreter is fully initialized
This commit is contained in:
parent
159658521c
commit
a19781b56a
|
@ -11,6 +11,8 @@ sf::Sound McRFPy_API::sfx;
|
|||
|
||||
std::shared_ptr<PyFont> McRFPy_API::default_font;
|
||||
std::shared_ptr<PyTexture> McRFPy_API::default_texture;
|
||||
PyObject* McRFPy_API::mcrf_module;
|
||||
|
||||
|
||||
static PyMethodDef mcrfpyMethods[] = {
|
||||
{"registerPyAction", McRFPy_API::_registerPyAction, METH_VARARGS,
|
||||
|
@ -82,7 +84,7 @@ PyObject* PyInit_mcrfpy()
|
|||
auto t = pytypes[i];
|
||||
while (t != nullptr)
|
||||
{
|
||||
PyType_Ready(t);
|
||||
/*std::cout << */ PyType_Ready(t); /*<< std::endl; */
|
||||
PyModule_AddType(m, t);
|
||||
t = pytypes[i++];
|
||||
}
|
||||
|
@ -90,8 +92,11 @@ PyObject* PyInit_mcrfpy()
|
|||
// Add default_font and default_texture to module
|
||||
McRFPy_API::default_font = std::make_shared<PyFont>("assets/JetbrainsMono.ttf");
|
||||
McRFPy_API::default_texture = std::make_shared<PyTexture>("assets/kenney_tinydungeon.png", 16, 16);
|
||||
PyModule_AddObject(m, "default_font", McRFPy_API::default_font->pyObject());
|
||||
PyModule_AddObject(m, "default_texture", McRFPy_API::default_texture->pyObject());
|
||||
//PyModule_AddObject(m, "default_font", McRFPy_API::default_font->pyObject());
|
||||
//PyModule_AddObject(m, "default_texture", McRFPy_API::default_texture->pyObject());
|
||||
PyModule_AddObject(m, "default_font", Py_None);
|
||||
PyModule_AddObject(m, "default_texture", Py_None);
|
||||
//McRFPy_API::mcrf_module = m;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -143,6 +148,9 @@ PyStatus init_python(const char *program_name)
|
|||
#endif
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
|
||||
PyConfig_Clear(&config);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -172,6 +180,15 @@ void McRFPy_API::api_init() {
|
|||
//texture_sprite_count = texture_width * texture_height;
|
||||
//texture.setSmooth(false);
|
||||
|
||||
// Add default_font and default_texture to module
|
||||
McRFPy_API::mcrf_module = PyImport_ImportModule("mcrfpy");
|
||||
std::cout << PyUnicode_AsUTF8(PyObject_Repr(McRFPy_API::mcrf_module)) << std::endl;
|
||||
|
||||
//PyModule_AddObject(McRFPy_API::mcrf_module, "default_font", McRFPy_API::default_font->pyObject());
|
||||
PyObject_SetAttrString(McRFPy_API::mcrf_module, "default_font", McRFPy_API::default_font->pyObject());
|
||||
//PyModule_AddObject(McRFPy_API::mcrf_module, "default_texture", McRFPy_API::default_texture->pyObject());
|
||||
PyObject_SetAttrString(McRFPy_API::mcrf_module, "default_texture", McRFPy_API::default_texture->pyObject());
|
||||
|
||||
//sprite.setTexture(texture);
|
||||
//sprite.setScale(sf::Vector2f(4.0f, 4.0f));
|
||||
//setSpriteTexture(0);
|
||||
|
|
|
@ -19,6 +19,7 @@ private:
|
|||
|
||||
|
||||
public:
|
||||
static PyObject* mcrf_module;
|
||||
static std::shared_ptr<PyFont> default_font;
|
||||
static std::shared_ptr<PyTexture> default_texture;
|
||||
//inline static sf::Sprite sprite;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "PyTexture.h"
|
||||
|
||||
#include "McRFPy_API.h"
|
||||
|
||||
PyTexture::PyTexture(std::string filename, int sprite_w, int sprite_h)
|
||||
: source(filename), sprite_width(sprite_w), sprite_height(sprite_h)
|
||||
|
@ -28,9 +28,36 @@ sf::Sprite PyTexture::sprite(int index, sf::Vector2f pos, sf::Vector2f s)
|
|||
|
||||
PyObject* PyTexture::pyObject()
|
||||
{
|
||||
PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyTextureType, 0);
|
||||
// method 1: works but with type weirdness
|
||||
//PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyTextureType, 0);
|
||||
//Py_SET_TYPE(obj, &mcrfpydef::PyTextureType);
|
||||
|
||||
// method 2: does not work (segfault on use of the mcrfpy.Texture object)
|
||||
//PyObject* obj = PyTexture::pynew(&mcrfpydef::PyTextureType, Py_None, Py_None);
|
||||
|
||||
// method 3: does not work (segfault on use of the mcrfpy.Texture object)
|
||||
std::cout << "Find type" << std::endl;
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Texture");
|
||||
//auto type = obj->ob_type;
|
||||
//auto type = &mcrfpydef::PyTextureType;
|
||||
//std::cout << "assigned value 0x" << std::hex << reinterpret_cast<long>(type) << std::endl;
|
||||
//std::cout << "Found PyTextureType: " << PyUnicode_AsUTF8(PyObject_Repr((PyObject*)type)) << std::endl;
|
||||
//std::cout << "PyTextureType metatype: " << PyUnicode_AsUTF8(PyObject_Repr((PyObject_Type((PyObject*)type)))) << std::endl;
|
||||
//std::cout << "tp_alloc: 0x" << std::hex << reinterpret_cast <long>(type->tp_alloc) << std::endl <<
|
||||
// "tp_new: 0x" << std::hex << reinterpret_cast<long>(type->tp_new) << std::endl;
|
||||
//PyObject* obj = ((PyTypeObject*)type)->tp_new((PyTypeObject*)type, Py_None, Py_None);
|
||||
PyObject* obj = PyTexture::pynew(type, Py_None, Py_None);
|
||||
//Py_SET_TYPE(obj, type);
|
||||
|
||||
// method 4: call the type object?
|
||||
|
||||
std::cout << "Instantiated" << std::endl;
|
||||
//Py_SET_TYPE(obj, &mcrfpydef::PyTextureType);
|
||||
|
||||
//PyObject_CallFunction(&mcrfpydef::PyTextureType,
|
||||
try {
|
||||
((PyTextureObject*)obj)->data = shared_from_this();
|
||||
std::cout << "Sideloaded texture: " << PyUnicode_AsUTF8(PyObject_Repr(obj)) << std::endl;
|
||||
}
|
||||
catch (std::bad_weak_ptr& e)
|
||||
{
|
||||
|
@ -40,6 +67,22 @@ PyObject* PyTexture::pyObject()
|
|||
return obj;
|
||||
}
|
||||
|
||||
PyObject* PyTexture::repr(PyObject* obj)
|
||||
{
|
||||
PyTextureObject* self = (PyTextureObject*)obj;
|
||||
std::ostringstream ss;
|
||||
if (!self->data)
|
||||
{
|
||||
ss << "<Texture [invalid internal object]>";
|
||||
std::string repr_str = ss.str();
|
||||
return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace");
|
||||
}
|
||||
auto& ptex = *(self->data);
|
||||
ss << "<Texture " << ptex.sheet_height << " rows, " << ptex.sheet_width << " columns; " << ptex.sprite_width << "x" << ptex.sprite_height << "px sprites. source='" << ptex.source << "'>";
|
||||
std::string repr_str = ss.str();
|
||||
return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace");
|
||||
}
|
||||
|
||||
Py_hash_t PyTexture::hash(PyObject* obj)
|
||||
{
|
||||
auto self = (PyTextureObject*)obj;
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
sf::Sprite sprite(int index, sf::Vector2f pos = sf::Vector2f(0, 0), sf::Vector2f s = sf::Vector2f(1.0, 1.0));
|
||||
|
||||
PyObject* pyObject();
|
||||
static PyObject* repr(PyObject*);
|
||||
static Py_hash_t hash(PyObject*);
|
||||
static int init(PyTextureObject*, PyObject*, PyObject*);
|
||||
static PyObject* pynew(PyTypeObject* type, PyObject* args=NULL, PyObject* kwds=NULL);
|
||||
|
@ -31,10 +32,12 @@ namespace mcrfpydef {
|
|||
.tp_name = "mcrfpy.Texture",
|
||||
.tp_basicsize = sizeof(PyTextureObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_repr = PyTexture::repr,
|
||||
.tp_hash = PyTexture::hash,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = PyDoc_STR("SFML Texture Object"),
|
||||
//.tp_base = &PyBaseObject_Type,
|
||||
.tp_init = (initproc)PyTexture::init,
|
||||
.tp_new = PyTexture::pynew,
|
||||
.tp_new = PyType_GenericNew, //PyTexture::pynew,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@ import mcrfpy
|
|||
font = mcrfpy.Font("assets/JetbrainsMono.ttf")
|
||||
texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16)
|
||||
|
||||
print("[game.py] Default texture:")
|
||||
print(mcrfpy.default_texture)
|
||||
print(type(mcrfpy.default_texture))
|
||||
|
||||
# build test widgets
|
||||
|
||||
mcrfpy.createScene("pytest")
|
||||
|
|
Loading…
Reference in New Issue