diff --git a/rwgame/CMakeLists.txt b/rwgame/CMakeLists.txt index 3691edbe..a0d236b3 100644 --- a/rwgame/CMakeLists.txt +++ b/rwgame/CMakeLists.txt @@ -19,6 +19,9 @@ set(RWGAME_SOURCES StateManager.cpp State.cpp + MenuSystem.hpp + MenuSystem.cpp + states/LoadingState.hpp states/LoadingState.cpp states/IngameState.hpp diff --git a/rwgame/MenuSystem.cpp b/rwgame/MenuSystem.cpp new file mode 100644 index 00000000..e69de29b diff --git a/rwgame/MenuSystem.hpp b/rwgame/MenuSystem.hpp index 220d73d8..40c663c4 100644 --- a/rwgame/MenuSystem.hpp +++ b/rwgame/MenuSystem.hpp @@ -21,27 +21,35 @@ constexpr const char* kOptionsId = "FET_OPT"; constexpr const char* kQuitGameId = "FET_QG"; } +/** + * @brief Implements user navigable menus + * + * This is a temporary implementation + */ class Menu { - int font; - public: - Menu(int font = MenuDefaults::kFont) : font(font), activeEntry(-1) { - } - - struct MenuEntry { + /** + * @brief Handles rendering and dispatch of menu items + */ + class MenuEntry { GameString text; - float _size; + float size; + std::function callback; - MenuEntry(const GameString& n, float size = 30.f) - : text(n), _size(size) { + public: + MenuEntry(const std::string& n, std::function cb) + : text(GameStringUtil::fromString(n)), size(30.f), callback(cb) { + } + MenuEntry(const GameString& n, std::function cb, + float size = 30.f) + : text(n), size(size), callback(cb) { } - float getHeight() { - return _size; + float getHeight() const { + return size; } - virtual void draw(int font, bool active, GameRenderer* r, - glm::vec2& basis) { + void draw(int font, bool active, GameRenderer* r, glm::vec2& basis) { TextRenderer::TextInfo ti; ti.font = font; ti.screenPosition = basis; @@ -56,16 +64,6 @@ public: basis.y += getHeight(); } - virtual void activate(float clickX, float clickY) = 0; - }; - - struct Entry : public MenuEntry { - std::function callback; - - Entry(const GameString& title, std::function cb, float size) - : MenuEntry(title, size), callback(cb) { - } - void activate(float clickX, float clickY) { RW_UNUSED(clickX); RW_UNUSED(clickY); @@ -73,19 +71,28 @@ public: } }; - static std::shared_ptr lambda(const GameString& n, - std::function callback, - float size = 30.f) { - return std::shared_ptr(new Entry(n, callback, size)); + Menu(std::vector initial, int font = MenuDefaults::kFont) + : activeEntry(-1), font(font), entries(std::move(initial)) { } - static std::shared_ptr lambda(const std::string& n, - std::function callback, - float size = 30.f) { - return lambda(GameStringUtil::fromString(n), callback, size); + /** + * @brief creates a menu from the given menu items + * @return a shared pointer to the menu with the items + */ + static std::shared_ptr create(std::vector items, + int font = MenuDefaults::kFont) { + return std::make_shared(std::move(items), font); } - std::vector> entries; + Menu& lambda(const GameString& n, std::function callback) { + entries.emplace_back(n, callback, 30.f); + return *this; + } + + Menu& lambda(const std::string& n, std::function callback) { + entries.emplace_back(GameStringUtil::fromString(n), callback, 30.f); + return *this; + } /** * Active Entry index @@ -94,10 +101,6 @@ public: glm::vec2 offset; - void addEntry(std::shared_ptr entry) { - entries.push_back(entry); - } - void draw(GameRenderer* r) { glm::vec2 basis(offset); for (size_t i = 0; i < entries.size(); ++i) { @@ -105,18 +108,18 @@ public: if (activeEntry >= 0 && i == (unsigned)activeEntry) { active = true; } - entries[i]->draw(font, active, r, basis); + entries[i].draw(font, active, r, basis); } } void hover(const float x, const float y) { glm::vec2 c(x - offset.x, y - offset.y); for (size_t i = 0; i < entries.size(); ++i) { - if (c.y > 0.f && c.y < entries[i]->getHeight()) { + if (c.y > 0.f && c.y < entries[i].getHeight()) { activeEntry = i; return; } else { - c.y -= entries[i]->getHeight(); + c.y -= entries[i].getHeight(); } } } @@ -124,11 +127,11 @@ public: void click(const float x, const float y) { glm::vec2 c(x - offset.x, y - offset.y); for (auto it = entries.begin(); it != entries.end(); ++it) { - if (c.y > 0.f && c.y < (*it)->getHeight()) { - (*it)->activate(c.x, c.y); + if (c.y > 0.f && c.y < (*it).getHeight()) { + (*it).activate(c.x, c.y); return; } else { - c.y -= (*it)->getHeight(); + c.y -= (*it).getHeight(); } } } @@ -136,7 +139,7 @@ public: // Activates the menu entry at the current active index. void activate() { if (activeEntry >= 0 && (unsigned)activeEntry < entries.size()) { - entries[activeEntry]->activate(0.f, 0.f); + entries[activeEntry].activate(0.f, 0.f); } } @@ -148,6 +151,14 @@ public: activeEntry = entries.size() - 1; } } + + const std::vector& getEntries() const { + return entries; + } + +private: + int font; + std::vector entries; }; #endif diff --git a/rwgame/State.hpp b/rwgame/State.hpp index 7a918e7d..58c53f7d 100644 --- a/rwgame/State.hpp +++ b/rwgame/State.hpp @@ -12,13 +12,12 @@ class StateManager; class State { public: - // Helper for global menu behaviour - Menu* currentMenu; - Menu* nextMenu; + std::shared_ptr menu; + std::shared_ptr nextMenu; RWGame* game; - State(RWGame* game) : currentMenu(nullptr), nextMenu(nullptr), game(game) { + State(RWGame* game) : game(game) { } virtual void enter() = 0; @@ -33,24 +32,18 @@ public: } virtual ~State() { - if (getCurrentMenu()) { - delete getCurrentMenu(); - } } - void enterMenu(Menu* menu) { + void enterMenu(const std::shared_ptr& menu) { nextMenu = menu; } Menu* getCurrentMenu() { if (nextMenu) { - if (currentMenu) { - delete currentMenu; - } - currentMenu = nextMenu; + menu = nextMenu; nextMenu = nullptr; } - return currentMenu; + return menu.get(); } virtual void handleEvent(const SDL_Event& e); @@ -72,8 +65,11 @@ public: private: bool hasexited_ = false; + protected: - void done() { hasexited_ = true; } + void done() { + hasexited_ = true; + } }; #endif diff --git a/rwgame/states/DebugState.cpp b/rwgame/states/DebugState.cpp index 5a01d662..7290941d 100644 --- a/rwgame/states/DebugState.cpp +++ b/rwgame/states/DebugState.cpp @@ -11,6 +11,7 @@ #include "RWGame.hpp" constexpr float kDebugEntryHeight = 14.f; +constexpr int kDebugFont = 2; const glm::vec2 kDebugMenuOffset = glm::vec2(10.f, 50.f); static void jumpCharacter(RWGame* game, CharacterObject* player, @@ -29,195 +30,119 @@ static void jumpCharacter(RWGame* game, CharacterObject* player, } } -Menu* DebugState::createDebugMenu() { +std::shared_ptr DebugState::createDebugMenu() { CharacterObject* player = nullptr; if (game->getPlayer()) { player = game->getPlayer()->getCharacter(); } - Menu* m = new Menu(2); - m->offset = kDebugMenuOffset; -#if 0 - m->addEntry(Menu::lambda("Random Vehicle", [this] { - auto it = getWorld()->vehicleTypes.begin(); - std::uniform_int_distribution uniform(0, 3); - for(size_t i = 0, n = uniform(getWorld()->randomEngine); i != n; i++) { - it++; - } - spawnVehicle(it->first); - }, entryHeight)); - m->addEntry(Menu::lambda("Open All Doors/Flaps", [=] { - auto pc = getWorld()->state->player->getCharacter(); - auto pv = pc->getCurrentVehicle(); - if( pv ) { - for(auto& it : pv->_hingedObjects) { - pv->setHingeLocked(it.first, false); - } - } - }, entryHeight)); + auto menu = Menu::create( + {{"Jump to Debug Camera", + [=] { + jumpCharacter(game, player, + _debugCam.position + + _debugCam.rotation * glm::vec3(3.f, 0.f, 0.f), + false); + }}, + {"-Map", [=] { this->enterMenu(createMapMenu()); }}, + {"-Vehicles", [=] { this->enterMenu(createVehicleMenu()); }}, + {"-AI", [=] { this->enterMenu(createAIMenu()); }}, + {"-Weapons", [=] { this->enterMenu(createWeaponMenu()); }}, + {"Set Super Jump", [=] { player->setJumpSpeed(20.f); }}, + {"Set Normal Jump", + [=] { player->setJumpSpeed(CharacterObject::DefaultJumpSpeed); }}, + {"Full Health", [=] { player->getCurrentState().health = 100.f; }}, + {"Full Armour", [=] { player->getCurrentState().armour = 100.f; }}, + {"Cull Here", + [=] { game->getRenderer().setCullOverride(true, _debugCam); }}}, + kDebugFont); - m->addEntry(Menu::lambda("Spawn Pedestrians", [=] { - glm::vec3 hit, normal; - if(game->hitWorldRay(hit, normal)) { - glm::vec3 spawnPos = hit + glm::vec3(-5, 0.f, 0.0) + normal; - size_t k = 1; - // Spawn every pedestrian. - for(auto it = getWorld()->pedestrianTypes.begin(); - it != getWorld()->pedestrianTypes.end(); ++it) { - getWorld()->createPedestrian(it->first, spawnPos); - spawnPos += glm::vec3(2.5, 0, 0); - if((k++ % 6) == 0) { spawnPos += glm::vec3(-15, -2.5, 0); } - } - } - }, entryHeight)); - - int vehiclesMax = 16, i = 0; - for( auto& v : getWorld()->vehicleTypes ) { - if( (i++) > vehiclesMax ) break; - m->addEntry(Menu::lambda(v.second->handlingID, [=] { - spawnVehicle(v.first); - }, entryHeight)); - } -#endif - m->addEntry(Menu::lambda("Jump to Debug Camera", - [=] { - jumpCharacter(game, player, - _debugCam.position + - _debugCam.rotation * - glm::vec3(3.f, 0.f, 0.f), - false); - }, - kDebugEntryHeight)); - - m->addEntry(Menu::lambda("-Map", [=] { this->enterMenu(createMapMenu()); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda("-Vehicles", - [=] { this->enterMenu(createVehicleMenu()); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda("-AI", [=] { this->enterMenu(createAIMenu()); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda("-Weapons", - [=] { this->enterMenu(createWeaponMenu()); }, - kDebugEntryHeight)); - - m->addEntry(Menu::lambda("Set Super Jump", - [=] { player->setJumpSpeed(20.f); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Set Normal Jump", - [=] { player->setJumpSpeed(CharacterObject::DefaultJumpSpeed); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda("Full Health", - [=] { player->getCurrentState().health = 100.f; }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda("Full Armour", - [=] { player->getCurrentState().armour = 100.f; }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Cull Here", - [=] { game->getRenderer().setCullOverride(true, _debugCam); }, - kDebugEntryHeight)); + menu->offset = kDebugMenuOffset; // Optional block if the player is in a vehicle auto cv = player->getCurrentVehicle(); if (cv) { - m->addEntry(Menu::lambda( - "Flip vehicle", - [=] { - cv->setRotation( - cv->getRotation() * - glm::quat(glm::vec3(0.f, glm::pi(), 0.f))); - }, - kDebugEntryHeight)); + menu->lambda("Flip vehicle", [=] { + cv->setRotation(cv->getRotation() * + glm::quat(glm::vec3(0.f, glm::pi(), 0.f))); + }); } - return m; + return menu; } -Menu* DebugState::createMapMenu() { +std::shared_ptr DebugState::createMapMenu() { CharacterObject* player = nullptr; if (game->getPlayer()) { player = game->getPlayer()->getCharacter(); } - Menu* m = new Menu(2); - m->offset = kDebugMenuOffset; + auto menu = Menu::create( + {{"Back", [=] { enterMenu(createDebugMenu()); }}, + {"Jump to Docks", + [=] { + jumpCharacter(game, player, glm::vec3(1390.f, -837.f, 100.f)); + }}, + {"Jump to Garage", + [=] { jumpCharacter(game, player, glm::vec3(270.f, -605.f, 40.f)); }}, + {"Jump to Airport", + [=] { + jumpCharacter(game, player, glm::vec3(-950.f, -980.f, 12.f)); + }}, + {"Jump to Hideout", + [=] { + jumpCharacter(game, player, glm::vec3(875.0, -309.0, 100.0)); + }}, + {"Jump to Luigi's", + [=] { + jumpCharacter(game, player, glm::vec3(902.75, -425.56, 100.0)); + }}, + {"Jump to Hospital", + [=] { + jumpCharacter(game, player, glm::vec3(1123.77, -569.15, 100.0)); + }}, + {"Unsolid garage doors", + [=] { - m->addEntry(Menu::lambda("Back", - [=] { this->enterMenu(createDebugMenu()); }, - kDebugEntryHeight)); + std::vector garageDoorModels{ + "8ballsuburbandoor", "amcogaragedoor", + "bankjobdoor", "bombdoor", + "crushercrush", "crushertop", + "door2_garage", "door3_garage", + "door4_garage", "door_bombshop", + "door_col_compnd_01", "door_col_compnd_02", + "door_col_compnd_03", "door_col_compnd_04", + "door_col_compnd_05", "door_jmsgrage", + "door_sfehousegrge", "double_garage_dr", + "impex_door", "impexpsubgrgdoor", + "ind_plyrwoor", "ind_slidedoor", + "jamesgrge_kb", "leveldoor2", + "oddjgaragdoor", "plysve_gragedoor", + "SalvGarage", "shedgaragedoor", + "Sub_sprayshopdoor", "towergaragedoor1", + "towergaragedoor2", "towergaragedoor3", + "vheistlocdoor"}; - m->addEntry(Menu::lambda( - "Jump to Docks", - [=] { jumpCharacter(game, player, glm::vec3(1390.f, -837.f, 100.f)); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Jump to Garage", - [=] { jumpCharacter(game, player, glm::vec3(270.f, -605.f, 40.f)); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Jump to Airport", - [=] { jumpCharacter(game, player, glm::vec3(-950.f, -980.f, 12.f)); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Jump to Hideout", - [=] { jumpCharacter(game, player, glm::vec3(875.0, -309.0, 100.0)); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Jump to Luigi's", - [=] { jumpCharacter(game, player, glm::vec3(902.75, -425.56, 100.0)); }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Jump to Hospital", - [=] { - jumpCharacter(game, player, glm::vec3(1123.77, -569.15, 100.0)); - }, - kDebugEntryHeight)); - m->addEntry(Menu::lambda( - "Unsolid garage doors", - [=] { + auto gw = game->getWorld(); + for (auto& i : gw->instancePool.objects) { + auto obj = static_cast(i.second); + if (std::find(garageDoorModels.begin(), + garageDoorModels.end(), + obj->getModelInfo()->name) != + garageDoorModels.end()) { + obj->setSolid(false); + } + } + }}}, + kDebugFont); - std::vector garageDoorModels{ - "8ballsuburbandoor", "amcogaragedoor", - "bankjobdoor", "bombdoor", - "crushercrush", "crushertop", - "door2_garage", "door3_garage", - "door4_garage", "door_bombshop", - "door_col_compnd_01", "door_col_compnd_02", - "door_col_compnd_03", "door_col_compnd_04", - "door_col_compnd_05", "door_jmsgrage", - "door_sfehousegrge", "double_garage_dr", - "impex_door", "impexpsubgrgdoor", - "ind_plyrwoor", "ind_slidedoor", - "jamesgrge_kb", "leveldoor2", - "oddjgaragdoor", "plysve_gragedoor", - "SalvGarage", "shedgaragedoor", - "Sub_sprayshopdoor", "towergaragedoor1", - "towergaragedoor2", "towergaragedoor3", - "vheistlocdoor"}; - - auto gw = game->getWorld(); - for (auto& i : gw->instancePool.objects) { - auto obj = static_cast(i.second); - if (std::find(garageDoorModels.begin(), garageDoorModels.end(), - obj->getModelInfo()->name) != - garageDoorModels.end()) { - obj->setSolid(false); - } - } - }, - kDebugEntryHeight)); - - return m; + menu->offset = kDebugMenuOffset; + return menu; } -Menu* DebugState::createVehicleMenu() { - Menu* m = new Menu(2); - m->offset = kDebugMenuOffset; - - m->addEntry(Menu::lambda("Back", - [=] { this->enterMenu(createDebugMenu()); }, - kDebugEntryHeight)); +std::shared_ptr DebugState::createVehicleMenu() { + auto menu = Menu::create({{"Back", [=] { enterMenu(createDebugMenu()); }}}, + kDebugFont); const std::map kVehicleTypes = { {"Landstalker", 90}, {"Taxi", 110}, {"Firetruck", 97}, @@ -228,20 +153,16 @@ Menu* DebugState::createVehicleMenu() { }; for (auto& e : kVehicleTypes) { - m->addEntry(Menu::lambda(e.first, [=] { spawnVehicle(e.second); }, - kDebugEntryHeight)); + menu->lambda(e.first, [=] { spawnVehicle(e.second); }); } - return m; + menu->offset = kDebugMenuOffset; + return menu; } -Menu* DebugState::createAIMenu() { - Menu* m = new Menu(2); - m->offset = kDebugMenuOffset; - - m->addEntry(Menu::lambda("Back", - [=] { this->enterMenu(createDebugMenu()); }, - kDebugEntryHeight)); +std::shared_ptr DebugState::createAIMenu() { + auto menu = Menu::create( + {{"Back", [=] { this->enterMenu(createDebugMenu()); }}}, kDebugFont); const std::map kPedTypes = { {"Triad", 12}, {"Cop", 1}, {"SWAT", 2}, @@ -249,42 +170,35 @@ Menu* DebugState::createAIMenu() { }; for (auto& e : kPedTypes) { - m->addEntry(Menu::lambda(e.first + " Follower", - [=] { spawnFollower(e.second); }, - kDebugEntryHeight)); + menu->lambda(e.first + " Follower", [=] { spawnFollower(e.second); }); } - m->addEntry(Menu::lambda( - "Kill All Peds", - [=] { - for (auto& p : game->getWorld()->pedestrianPool.objects) { - if (p.second->getLifetime() == GameObject::PlayerLifetime) { - continue; - } - p.second->takeDamage({p.second->getPosition(), - p.second->getPosition(), 100.f, - GameObject::DamageInfo::Explosion, 0.f}); + menu->lambda("Kill All Peds", [=] { + for (auto& p : game->getWorld()->pedestrianPool.objects) { + if (p.second->getLifetime() == GameObject::PlayerLifetime) { + continue; } - }, - kDebugEntryHeight)); - return m; + p.second->takeDamage({p.second->getPosition(), + p.second->getPosition(), 100.f, + GameObject::DamageInfo::Explosion, 0.f}); + } + }); + + menu->offset = kDebugMenuOffset; + return menu; } -Menu* DebugState::createWeaponMenu() { - Menu* m = new Menu(2); - m->offset = kDebugMenuOffset; - - m->addEntry(Menu::lambda("Back", - [=] { this->enterMenu(createDebugMenu()); }, - kDebugEntryHeight)); +std::shared_ptr DebugState::createWeaponMenu() { + auto menu = Menu::create( + {{"Back", [=] { this->enterMenu(createDebugMenu()); }}}, kDebugFont); for (int i = 1; i < kMaxInventorySlots; ++i) { auto& name = getWorld()->data->weaponData[i]->name; - m->addEntry( - Menu::lambda(name, [=] { giveItem(i); }, kDebugEntryHeight)); + menu->lambda(name, [=] { giveItem(i); }); } - return m; + menu->offset = kDebugMenuOffset; + return menu; } DebugState::DebugState(RWGame* game, const glm::vec3& vp, const glm::quat& vd) diff --git a/rwgame/states/DebugState.hpp b/rwgame/states/DebugState.hpp index 57965091..5f636864 100644 --- a/rwgame/states/DebugState.hpp +++ b/rwgame/states/DebugState.hpp @@ -11,11 +11,11 @@ class DebugState : public State { bool _sonicMode = false; bool _invertedY; - Menu* createDebugMenu(); - Menu* createMapMenu(); - Menu* createVehicleMenu(); - Menu* createAIMenu(); - Menu* createWeaponMenu(); + std::shared_ptr createDebugMenu(); + std::shared_ptr createMapMenu(); + std::shared_ptr createVehicleMenu(); + std::shared_ptr createAIMenu(); + std::shared_ptr createWeaponMenu(); public: DebugState(RWGame* game, const glm::vec3& vp = {}, diff --git a/rwgame/states/MenuState.cpp b/rwgame/states/MenuState.cpp index ac31770d..a682eb30 100644 --- a/rwgame/states/MenuState.cpp +++ b/rwgame/states/MenuState.cpp @@ -13,27 +13,24 @@ MenuState::MenuState(RWGame* game) : State(game) { void MenuState::enterMainMenu() { auto& t = game->getGameData().texts; - Menu* m = new Menu; - m->offset = glm::vec2(200.f, 200.f); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kStartGameId), [=] { - StateManager::get().enter(game); - })); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kLoadGameId), - [=] { enterLoadMenu(); })); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kDebugId), [=] { - StateManager::get().enter(game, true, "test"); - })); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kOptionsId), - [] { RW_UNIMPLEMENTED("Options Menu"); })); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kQuitGameId), - [] { StateManager::get().clear(); })); - this->enterMenu(m); + auto menu = Menu::create( + {{t.text(MenuDefaults::kStartGameId), + [=] { StateManager::get().enter(game); }}, + {t.text(MenuDefaults::kLoadGameId), [=] { enterLoadMenu(); }}, + {t.text(MenuDefaults::kDebugId), + [=] { StateManager::get().enter(game, true, "test"); }}, + {t.text(MenuDefaults::kOptionsId), + [] { RW_UNIMPLEMENTED("Options Menu"); }}, + {t.text(MenuDefaults::kQuitGameId), + [] { StateManager::get().clear(); }}}); + menu->offset = glm::vec2(200.f, 200.f); + + enterMenu(menu); } void MenuState::enterLoadMenu() { - Menu* m = new Menu; - m->offset = glm::vec2(20.f, 30.f); - m->addEntry(Menu::lambda("BACK", [=] { enterMainMenu(); })); + auto menu = Menu::create({{"BACK", [=] { enterMainMenu(); }}}); + auto saves = SaveGame::getAllSaveGameInfo(); for (SaveGameInfo& save : saves) { if (save.valid) { @@ -49,12 +46,14 @@ void MenuState::enterLoadMenu() { StateManager::get().enter(game, false); game->loadGame(save.savePath); }; - m->addEntry(Menu::lambda(name, loadsave, 20.f)); + menu->lambda(name, loadsave); } else { - m->addEntry(Menu::lambda("CORRUPT", [=] {})); + menu->lambda("CORRUPT", [=] {}); } } - this->enterMenu(m); + menu->offset = glm::vec2(20.f, 30.f); + + enterMenu(menu); } void MenuState::enter() { diff --git a/rwgame/states/PauseState.cpp b/rwgame/states/PauseState.cpp index 37fd5edb..dd5b5a92 100644 --- a/rwgame/states/PauseState.cpp +++ b/rwgame/states/PauseState.cpp @@ -4,15 +4,14 @@ PauseState::PauseState(RWGame* game) : State(game) { auto& t = game->getGameData().texts; - Menu* m = new Menu; - m->offset = glm::vec2(200.f, 200.f); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kResumeGameId), - [&] { done(); })); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kOptionsId), - [] { std::cout << "Options" << std::endl; })); - m->addEntry(Menu::lambda(t.text(MenuDefaults::kQuitGameId), - [] { StateManager::get().clear(); })); - this->enterMenu(m); + auto menu = Menu::create( + {{t.text(MenuDefaults::kResumeGameId), [&] { done(); }}, + {t.text(MenuDefaults::kOptionsId), + [] { std::cout << "Options" << std::endl; }}, + {t.text(MenuDefaults::kQuitGameId), + [] { StateManager::get().clear(); }}}); + menu->offset = glm::vec2(200.f, 200.f); + enterMenu(menu); } void PauseState::enter() { diff --git a/tests/test_menu.cpp b/tests/test_menu.cpp index 233f61b1..703edfd8 100644 --- a/tests/test_menu.cpp +++ b/tests/test_menu.cpp @@ -6,8 +6,7 @@ BOOST_AUTO_TEST_SUITE(MenuUnitTests) BOOST_AUTO_TEST_CASE(menu_test_click) { bool clickered = false; - Menu test(0); - test.addEntry(Menu::lambda("Test", [&] { clickered = true; })); + Menu test({{"Test", [&] { clickered = true; }}}); BOOST_CHECK(!clickered); @@ -16,7 +15,7 @@ BOOST_AUTO_TEST_CASE(menu_test_click) { BOOST_CHECK(!clickered); - float h = test.entries.at(0)->getHeight(); + float h = test.getEntries().at(0).getHeight(); test.click(0.f, h + 1.f); @@ -29,9 +28,8 @@ BOOST_AUTO_TEST_CASE(menu_test_click) { BOOST_AUTO_TEST_CASE(menu_test_click_offset) { bool clickered = false; - Menu test(0); + Menu test({{"Test", [&] { clickered = true; }}}); test.offset = glm::vec2(200.f, 200.f); - test.addEntry(Menu::lambda("Test", [&] { clickered = true; })); BOOST_CHECK(!clickered); @@ -40,7 +38,7 @@ BOOST_AUTO_TEST_CASE(menu_test_click_offset) { BOOST_CHECK(!clickered); - float h = test.entries.at(0)->getHeight(); + float h = test.getEntries().at(0).getHeight(); test.click(201.f, 200.f + h + 1.f); @@ -53,9 +51,8 @@ BOOST_AUTO_TEST_CASE(menu_test_click_offset) { BOOST_AUTO_TEST_CASE(menu_test_active_index) { int clickindex = -1; - Menu test(0); - test.addEntry(Menu::lambda("Test1", [&] { clickindex = 0; })); - test.addEntry(Menu::lambda("Test2", [&] { clickindex = 1; })); + Menu test({{"Test1", [&] { clickindex = 0; }}, + {"Test2", [&] { clickindex = 1; }}}); test.activate(); @@ -79,14 +76,13 @@ BOOST_AUTO_TEST_CASE(menu_test_active_index) { BOOST_AUTO_TEST_CASE(menu_test_hover_index) { int clickindex = -1; - Menu test(0); - test.addEntry(Menu::lambda("Test1", [&] { clickindex = 0; })); - test.addEntry(Menu::lambda("Test2", [&] { clickindex = 1; })); + Menu test({{"Test1", [&] { clickindex = 0; }}, + {"Test2", [&] { clickindex = 1; }}}); - test.hover(0.f, test.entries[0]->getHeight() - 0.1f); + test.hover(0.f, test.getEntries()[0].getHeight() - 0.1f); BOOST_CHECK(test.activeEntry == 0); - test.hover(0.f, test.entries[0]->getHeight() + 0.1f); + test.hover(0.f, test.getEntries()[0].getHeight() + 0.1f); BOOST_CHECK(test.activeEntry == 1); }