Switched UIFrame and Scene to store their UIDrawables in shared_ptr to vector, instead of directly to vector. Every object that can be exposed to Python has to be safely shareable so it doesn't become a segfault, and that includes the UIDrawable collections AND the UIDrawable members. So we get the terrifying type for collections of child elements: 'std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>>'. May I be forgiven for my sins

This commit is contained in:
John McCardle 2023-09-02 14:00:48 -04:00
parent a41d3d4a54
commit 0ef0a5d506
7 changed files with 32 additions and 15 deletions

View File

@ -121,7 +121,7 @@ void GameEngine::sUserInput()
} }
} }
std::vector<std::shared_ptr<UIDrawable>>* GameEngine::scene_ui(std::string target) std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> GameEngine::scene_ui(std::string target)
{ {
/* /*
// facts about maps // facts about maps
@ -136,5 +136,5 @@ std::vector<std::shared_ptr<UIDrawable>>* GameEngine::scene_ui(std::string targe
std::cout << "scenes[target]: " << (long)(scenes[target]) << std::endl; std::cout << "scenes[target]: " << (long)(scenes[target]) << std::endl;
*/ */
if (scenes.count(target) == 0) return NULL; if (scenes.count(target) == 0) return NULL;
return &scenes[target]->ui_elements; return scenes[target]->ui_elements;
} }

View File

@ -42,6 +42,6 @@ public:
std::vector<sf::SoundBuffer> sfxbuffers; std::vector<sf::SoundBuffer> sfxbuffers;
sf::Music music; sf::Music music;
sf::Sound sfx; sf::Sound sfx;
std::vector<std::shared_ptr<UIDrawable>>* scene_ui(std::string scene); std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> scene_ui(std::string scene);
}; };

View File

@ -1,7 +1,12 @@
#include "Scene.h" #include "Scene.h"
#include "UI.h"
//Scene::Scene() { game = 0; std::cout << "WARN: default Scene constructor called. (game = " << game << ")" << std::endl;}; //Scene::Scene() { game = 0; std::cout << "WARN: default Scene constructor called. (game = " << game << ")" << std::endl;};
Scene::Scene(GameEngine* g) { game = g; } Scene::Scene(GameEngine* g)
{
game = g;
ui_elements = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
}
void Scene::registerAction(int code, std::string name) void Scene::registerAction(int code, std::string name)
{ {
actions[code] = name; actions[code] = name;

View File

@ -39,6 +39,6 @@ public:
virtual bool registerActionInjected(int, std::string); virtual bool registerActionInjected(int, std::string);
virtual bool unregisterActionInjected(int, std::string); virtual bool unregisterActionInjected(int, std::string);
std::vector<std::shared_ptr<UIDrawable>> ui_elements; std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> ui_elements;
}; };

View File

@ -10,6 +10,7 @@ void UIDrawable::render()
UIFrame::UIFrame(): UIFrame::UIFrame():
x(0), y(0), w(0), h(0), outline(0) x(0), y(0), w(0), h(0), outline(0)
{ {
children = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
/* /*
pyOutlineColor = NULL; pyOutlineColor = NULL;
pyFillColor = NULL; pyFillColor = NULL;
@ -21,6 +22,7 @@ x(0), y(0), w(0), h(0), outline(0)
UIFrame::UIFrame(float _x, float _y, float _w, float _h): UIFrame::UIFrame(float _x, float _y, float _w, float _h):
x(_x), y(_y), w(_w), h(_h), outline(0) x(_x), y(_y), w(_w), h(_h), outline(0)
{ {
children = std::make_shared<std::vector<std::shared_ptr<UIDrawable>>>();
/* /*
pyOutlineColor = NULL; pyOutlineColor = NULL;
pyFillColor = NULL; pyFillColor = NULL;
@ -31,6 +33,7 @@ x(_x), y(_y), w(_w), h(_h), outline(0)
UIFrame::~UIFrame() UIFrame::~UIFrame()
{ {
children.reset();
/* /*
if (pyOutlineColor) Py_DECREF(pyOutlineColor); if (pyOutlineColor) Py_DECREF(pyOutlineColor);
else if (_outlineColor) delete _outlineColor; else if (_outlineColor) delete _outlineColor;
@ -64,7 +67,7 @@ void UIFrame::render(sf::Vector2f offset)
//if (_outlineColor) { box.setOutlineColor(outlineColor()); } //if (_outlineColor) { box.setOutlineColor(outlineColor()); }
//box.setOutlineThickness(outline); //box.setOutlineThickness(outline);
//Resources::game->getWindow().draw(box); //Resources::game->getWindow().draw(box);
for (auto drawable : children) { for (auto drawable : *children) {
drawable->render(offset + box.getPosition()); drawable->render(offset + box.getPosition());
} }
} }

View File

@ -38,7 +38,7 @@ public:
//Simulate RectangleShape //Simulate RectangleShape
float x, y, w, h, outline; float x, y, w, h, outline;
std::vector<std::shared_ptr<UIDrawable>> children; std::shared_ptr<std::vector<std::shared_ptr<UIDrawable>>> children;
void render(sf::Vector2f) override final; void render(sf::Vector2f) override final;
void move(sf::Vector2f); void move(sf::Vector2f);
@ -391,7 +391,7 @@ namespace mcrfpydef {
"outline=" << box.getOutlineThickness() << ", " << "outline=" << box.getOutlineThickness() << ", " <<
"fill_color=(" << (int)fc.r << ", " << (int)fc.g << ", " << (int)fc.b << ", " << (int)fc.a <<"), " << "fill_color=(" << (int)fc.r << ", " << (int)fc.g << ", " << (int)fc.b << ", " << (int)fc.a <<"), " <<
"outlinecolor=(" << (int)oc.r << ", " << (int)oc.g << ", " << (int)oc.b << ", " << (int)oc.a <<"), " << "outlinecolor=(" << (int)oc.r << ", " << (int)oc.g << ", " << (int)oc.b << ", " << (int)oc.a <<"), " <<
self->data->children.size() << " child" << (self->data->children.size() == 1 ? "" : "ren") << " objects" << self->data->children->size() << " child objects" <<
")>"; ")>";
} }
std::string repr_str = ss.str(); std::string repr_str = ss.str();

View File

@ -13,6 +13,9 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
//registerAction(ActionCode::KEY + sf::Keyboard::Up, "up"); //registerAction(ActionCode::KEY + sf::Keyboard::Up, "up");
//registerAction(ActionCode::KEY + sf::Keyboard::Down, "down"); //registerAction(ActionCode::KEY + sf::Keyboard::Down, "down");
// note - you can't use the pointer to UI elements in constructor.
// The scene map is still being assigned to, so this object can't be looked up.
/*
auto ui = Resources::game->scene_ui("uitest"); auto ui = Resources::game->scene_ui("uitest");
if (ui) if (ui)
{ {
@ -20,6 +23,7 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
} else { } else {
std::cout << "No UI vector was returned.\n"; std::cout << "No UI vector was returned.\n";
} }
*/
// Create a UI element or three? // Create a UI element or three?
auto e1 = std::make_shared<UIFrame>(100,150,400,400); auto e1 = std::make_shared<UIFrame>(100,150,400,400);
@ -28,21 +32,21 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
e1->box.setFillColor(sf::Color(255, 0, 0)); e1->box.setFillColor(sf::Color(255, 0, 0));
//e1.fillColor(sf::Color(255,0,0)); //e1.fillColor(sf::Color(255,0,0));
//if (ui) ui->push_back(e1); //if (ui) ui->push_back(e1);
ui_elements.push_back(e1); ui_elements->push_back(e1);
auto e1a = std::make_shared<UIFrame>(50,50,200,200); auto e1a = std::make_shared<UIFrame>(50,50,200,200);
e1a->box.setPosition(50, 50); e1a->box.setPosition(50, 50);
e1a->box.setSize(sf::Vector2f(200,200)); e1a->box.setSize(sf::Vector2f(200,200));
e1a->box.setFillColor(sf::Color(0, 255, 0)); e1a->box.setFillColor(sf::Color(0, 255, 0));
//e1a.fillColor(sf::Color(0, 255, 0)); //e1a.fillColor(sf::Color(0, 255, 0));
e1->children.push_back(e1a); e1->children->push_back(e1a);
auto e1aa = std::make_shared<UIFrame>(5,5,100,100); auto e1aa = std::make_shared<UIFrame>(5,5,100,100);
e1aa->box.setPosition(5, 5); e1aa->box.setPosition(5, 5);
e1aa->box.setSize(sf::Vector2f(100,100)); e1aa->box.setSize(sf::Vector2f(100,100));
e1aa->box.setFillColor(sf::Color(0, 0, 255)); e1aa->box.setFillColor(sf::Color(0, 0, 255));
//e1aa.fillColor(sf::Color(0, 0, 255)); //e1aa.fillColor(sf::Color(0, 0, 255));
e1a->children.push_back(e1aa); e1a->children->push_back(e1aa);
auto e2 = std::make_shared<UICaption>(); auto e2 = std::make_shared<UICaption>();
e2->text.setFont(game->getFont()); e2->text.setFont(game->getFont());
@ -51,12 +55,16 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
e2->text.setPosition(50, 250); e2->text.setPosition(50, 250);
//if (ui) ui->push_back(e2); //if (ui) ui->push_back(e2);
ui_elements.push_back(e2); ui_elements->push_back(e2);
//ui_elements.push_back(&e1); //ui_elements.push_back(&e1);
//ui_elements.push_back(&e2); //ui_elements.push_back(&e2);
/*
// note - you can't use the pointer to UI elements in constructor.
// The scene map is still being assigned to, so this object can't be looked up.
if (ui) if (ui)
std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl; std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl;
*/
} }
void UITestScene::update() void UITestScene::update()
@ -87,7 +95,8 @@ void UITestScene::sRender()
//for (auto e: ui_elements) //for (auto e: ui_elements)
//auto ui = Resources::game->scene_ui("uitest"); //auto ui = Resources::game->scene_ui("uitest");
//if (ui) //if (ui)
for (auto e: ui_elements) auto vec = *ui_elements;
for (auto e: vec)
{ {
//std::cout << "Rendering element\n"; //std::cout << "Rendering element\n";
if (e) if (e)