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
@ -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;
*/
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;
sf::Music music;
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 "UI.h"
//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)
{
actions[code] = name;

View File

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

View File

@ -38,7 +38,7 @@ public:
//Simulate RectangleShape
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 move(sf::Vector2f);
@ -391,7 +391,7 @@ namespace mcrfpydef {
"outline=" << box.getOutlineThickness() << ", " <<
"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 <<"), " <<
self->data->children.size() << " child" << (self->data->children.size() == 1 ? "" : "ren") << " objects" <<
self->data->children->size() << " child objects" <<
")>";
}
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::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");
if (ui)
{
@ -20,6 +23,7 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
} else {
std::cout << "No UI vector was returned.\n";
}
*/
// Create a UI element or three?
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.fillColor(sf::Color(255,0,0));
//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);
e1a->box.setPosition(50, 50);
e1a->box.setSize(sf::Vector2f(200,200));
e1a->box.setFillColor(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);
e1aa->box.setPosition(5, 5);
e1aa->box.setSize(sf::Vector2f(100,100));
e1aa->box.setFillColor(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>();
e2->text.setFont(game->getFont());
@ -51,12 +55,16 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
e2->text.setPosition(50, 250);
//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(&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)
std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl;
*/
}
void UITestScene::update()
@ -87,7 +95,8 @@ void UITestScene::sRender()
//for (auto e: ui_elements)
//auto ui = Resources::game->scene_ui("uitest");
//if (ui)
for (auto e: ui_elements)
auto vec = *ui_elements;
for (auto e: vec)
{
//std::cout << "Rendering element\n";
if (e)