Radical new example pattern for exposing a C++ class to Python

This commit is contained in:
John McCardle 2024-03-20 21:16:52 -04:00
parent 84a8886da2
commit 2cf8f94310
5 changed files with 80 additions and 5 deletions

View File

@ -24,3 +24,26 @@ sf::Sprite PyTexture::sprite(int index, sf::Vector2f pos, sf::Vector2f s)
sprite.setScale(s); sprite.setScale(s);
return sprite; return sprite;
} }
Py_hash_t PyTexture::hash(PyObject* obj)
{
auto self = (PyTextureObject*)obj;
//return static_cast<Py_hash_t>(reinterpret_cast<long>(self->data));
return reinterpret_cast<Py_hash_t>(self->data.get());
}
int PyTexture::init(PyTextureObject* self, PyObject* args, PyObject* kwds)
{
static const char* keywords[] = { "filename", "sprite_width", "sprite_height", nullptr };
char* filename;
int sprite_width, sprite_height;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sii", const_cast<char**>(keywords), &filename, &sprite_width, &sprite_height))
return -1;
self->data = std::make_shared<PyTexture>(filename, sprite_width, sprite_height);
return 0;
}
PyObject* PyTexture::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds)
{
return (PyObject*)type->tp_alloc(type, 0);
}

View File

@ -2,14 +2,63 @@
#include "Common.h" #include "Common.h"
#include "Python.h" #include "Python.h"
class PyTexture;
typedef struct {
PyObject_HEAD
std::shared_ptr<PyTexture> data;
} PyTextureObject;
class PyTexture class PyTexture
{ {
private: private:
sf::Texture texture; sf::Texture texture;
std::string source; std::string source;
int sheet_width, sheet_height; int sheet_width, sheet_height;
protected:
PyObject* self = 0;
public: public:
int sprite_width, sprite_height; // just use them read only, OK? int sprite_width, sprite_height; // just use them read only, OK?
PyTexture(std::string filename, int sprite_w, int sprite_h); PyTexture(std::string filename, int sprite_w, int sprite_h);
sf::Sprite sprite(int index, sf::Vector2f pos = sf::Vector2f(0, 0), sf::Vector2f s = sf::Vector2f(1.0, 1.0)); sf::Sprite sprite(int index, sf::Vector2f pos = sf::Vector2f(0, 0), sf::Vector2f s = sf::Vector2f(1.0, 1.0));
PyObject* pyObject();
static Py_hash_t hash(PyObject*);
static int init(PyTextureObject*, PyObject*, PyObject*);
static PyObject* pynew(PyTypeObject*, PyObject*, PyObject*);
}; };
/*
static int PyTexture_init(PyTextureObject* self, PyObject* args, PyObject* kwds)
{
//std::cout << "Init called\n";
static const char* keywords[] = { "filename", "grid_size", "grid_width", "grid_height", nullptr };
char* filename;
int grid_size, grid_width, grid_height;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "siii", const_cast<char**>(keywords), &filename, &grid_size, &grid_width, &grid_height))
{
return -1;
}
self->data = std::make_shared<PyTexture>(filename, grid_size, grid_size);
return 0;
}
*/
namespace mcrfpydef {
static PyTypeObject PyTextureType = {
.tp_name = "mcrfpy.Texture",
.tp_basicsize = sizeof(PyTextureObject),
.tp_itemsize = 0,
.tp_hash = PyTexture::hash,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("SFML Texture Object"),
.tp_init = (initproc)PyTexture::init,
.tp_new = PyTexture::pynew,
/*
[](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject*
{
PyTextureObject* self = (PyTextureObject*)type->tp_alloc(type, 0);
return (PyObject*)self;
}
*/
};
}

View File

@ -1085,10 +1085,12 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
* *
*/ */
/* // Definition moved to PyTexture.h
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
std::shared_ptr<PyTexture> data; std::shared_ptr<PyTexture> data;
} PyTextureObject; } PyTextureObject;
static int PyTexture_init(PyTextureObject* self, PyObject* args, PyObject* kwds) static int PyTexture_init(PyTextureObject* self, PyObject* args, PyObject* kwds)
{ {
@ -1121,6 +1123,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
return (PyObject*)self; return (PyObject*)self;
} }
}; };
*/
/* /*
* *

View File

@ -1,7 +1,7 @@
import mcrfpy import mcrfpy
mcrfpy.createScene("play") mcrfpy.createScene("play")
ui = mcrfpy.sceneUI("play") ui = mcrfpy.sceneUI("play")
t = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 12, 11) t = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) # 12, 11)
font = mcrfpy.Font("assets/JetbrainsMono.ttf") font = mcrfpy.Font("assets/JetbrainsMono.ttf")
frame_color = (64, 64, 128) frame_color = (64, 64, 128)

View File

@ -3,9 +3,9 @@ import mcrfpy
import cos_play import cos_play
# Universal stuff # Universal stuff
font = mcrfpy.Font("assets/JetbrainsMono.ttf") font = mcrfpy.Font("assets/JetbrainsMono.ttf")
texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 12, 11) texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11)
texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 12, 11) texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11)
texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 12, 11) texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11)
# Test stuff # Test stuff
mcrfpy.createScene("boom") mcrfpy.createScene("boom")
@ -125,7 +125,7 @@ stress_test()
mcrfpy.createScene("loading") mcrfpy.createScene("loading")
ui = mcrfpy.sceneUI("loading") ui = mcrfpy.sceneUI("loading")
#mcrfpy.setScene("loading") #mcrfpy.setScene("loading")
logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1, 1) logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1)
logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5)
ui.append(logo_sprite) ui.append(logo_sprite)
logo_sprite.click = lambda *args: mcrfpy.setScene("menu") logo_sprite.click = lambda *args: mcrfpy.setScene("menu")