settings observers lifecycle
This commit is contained in:
+38
-21
@@ -4,6 +4,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
#include "../delegates.h"
|
#include "../delegates.h"
|
||||||
@@ -30,13 +31,35 @@ public:
|
|||||||
virtual std::string toString() const = 0;
|
virtual std::string toString() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using observer_handler = std::shared_ptr<int>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Observers {
|
||||||
|
int nextid = 1;
|
||||||
|
std::unordered_map<int, consumer<T>> observers;
|
||||||
|
public:
|
||||||
|
observer_handler observe(consumer<T> callback) {
|
||||||
|
const int id = nextid++;
|
||||||
|
observers.emplace(id, callback);
|
||||||
|
return std::shared_ptr<int>(new int(id), [this](int* id) {
|
||||||
|
observers.erase(*id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify(T value) {
|
||||||
|
for (auto& entry : observers) {
|
||||||
|
entry.second(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class NumberSetting : public Setting {
|
class NumberSetting : public Setting {
|
||||||
protected:
|
protected:
|
||||||
number_t initial;
|
number_t initial;
|
||||||
number_t value;
|
number_t value;
|
||||||
number_t min;
|
number_t min;
|
||||||
number_t max;
|
number_t max;
|
||||||
std::vector<consumer<number_t>> consumers;
|
Observers<number_t> observers;
|
||||||
public:
|
public:
|
||||||
NumberSetting(
|
NumberSetting(
|
||||||
number_t value,
|
number_t value,
|
||||||
@@ -63,9 +86,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->value = value;
|
this->value = value;
|
||||||
for (auto& callback : consumers) {
|
observers.notify(value);
|
||||||
callback(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
number_t getMin() const {
|
number_t getMin() const {
|
||||||
@@ -80,12 +101,12 @@ public:
|
|||||||
return (value - min) / (max - min);
|
return (value - min) / (max - min);
|
||||||
}
|
}
|
||||||
|
|
||||||
void observe(consumer<number_t> callback) {
|
observer_handler observe(consumer<number_t> callback) {
|
||||||
consumers.push_back(callback);
|
return observers.observe(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void resetToDefault() override {
|
virtual void resetToDefault() override {
|
||||||
value = initial;
|
set(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string toString() const override;
|
virtual std::string toString() const override;
|
||||||
@@ -101,7 +122,7 @@ protected:
|
|||||||
integer_t value;
|
integer_t value;
|
||||||
integer_t min;
|
integer_t min;
|
||||||
integer_t max;
|
integer_t max;
|
||||||
std::vector<consumer<integer_t>> consumers;
|
Observers<integer_t> observers;
|
||||||
public:
|
public:
|
||||||
IntegerSetting(
|
IntegerSetting(
|
||||||
integer_t value,
|
integer_t value,
|
||||||
@@ -128,9 +149,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->value = value;
|
this->value = value;
|
||||||
for (auto& callback : consumers) {
|
observers.notify(value);
|
||||||
callback(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
integer_t getMin() const {
|
integer_t getMin() const {
|
||||||
@@ -145,12 +164,12 @@ public:
|
|||||||
return (value - min) / (max - min);
|
return (value - min) / (max - min);
|
||||||
}
|
}
|
||||||
|
|
||||||
void observe(consumer<integer_t> callback) {
|
observer_handler observe(consumer<integer_t> callback) {
|
||||||
consumers.push_back(callback);
|
return observers.observe(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void resetToDefault() override {
|
virtual void resetToDefault() override {
|
||||||
value = initial;
|
set(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string toString() const override;
|
virtual std::string toString() const override;
|
||||||
@@ -160,7 +179,7 @@ class FlagSetting : public Setting {
|
|||||||
protected:
|
protected:
|
||||||
bool initial;
|
bool initial;
|
||||||
bool value;
|
bool value;
|
||||||
std::vector<consumer<bool>> consumers;
|
Observers<bool> observers;
|
||||||
public:
|
public:
|
||||||
FlagSetting(
|
FlagSetting(
|
||||||
bool value,
|
bool value,
|
||||||
@@ -183,17 +202,15 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->value = value;
|
this->value = value;
|
||||||
for (auto& callback : consumers) {
|
observers.notify(value);
|
||||||
callback(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void observe(consumer<bool> callback) {
|
observer_handler observe(consumer<bool> callback) {
|
||||||
consumers.push_back(callback);
|
return observers.observe(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void resetToDefault() override {
|
virtual void resetToDefault() override {
|
||||||
value = initial;
|
set(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string toString() const override;
|
virtual std::string toString() const override;
|
||||||
|
|||||||
+8
-8
@@ -47,13 +47,13 @@ void addWorldGenerators() {
|
|||||||
WorldGenerators::addGenerator<FlatWorldGenerator>("core:flat");
|
WorldGenerators::addGenerator<FlatWorldGenerator>("core:flat");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void create_channel(std::string name, NumberSetting& setting) {
|
inline void create_channel(Engine* engine, std::string name, NumberSetting& setting) {
|
||||||
if (name != "master") {
|
if (name != "master") {
|
||||||
audio::create_channel(name);
|
audio::create_channel(name);
|
||||||
}
|
}
|
||||||
setting.observe([=](auto value) {
|
engine->keepAlive(setting.observe([=](auto value) {
|
||||||
audio::get_channel(name)->setVolume(value*value);
|
audio::get_channel(name)->setVolume(value*value);
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::Engine(EngineSettings& settings, EnginePaths* paths)
|
Engine::Engine(EngineSettings& settings, EnginePaths* paths)
|
||||||
@@ -64,11 +64,11 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths)
|
|||||||
throw initialize_error("could not initialize window");
|
throw initialize_error("could not initialize window");
|
||||||
}
|
}
|
||||||
audio::initialize(settings.audio.enabled);
|
audio::initialize(settings.audio.enabled);
|
||||||
create_channel("master", settings.audio.volumeMaster);
|
create_channel(this, "master", settings.audio.volumeMaster);
|
||||||
create_channel("regular", settings.audio.volumeRegular);
|
create_channel(this, "regular", settings.audio.volumeRegular);
|
||||||
create_channel("music", settings.audio.volumeMusic);
|
create_channel(this, "music", settings.audio.volumeMusic);
|
||||||
create_channel("ambient", settings.audio.volumeAmbient);
|
create_channel(this, "ambient", settings.audio.volumeAmbient);
|
||||||
create_channel("ui", settings.audio.volumeUI);
|
create_channel(this, "ui", settings.audio.volumeUI);
|
||||||
|
|
||||||
auto resdir = paths->getResources();
|
auto resdir = paths->getResources();
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -11,6 +11,7 @@
|
|||||||
#include "content/PacksManager.h"
|
#include "content/PacksManager.h"
|
||||||
#include "files/engine_paths.h"
|
#include "files/engine_paths.h"
|
||||||
#include "files/settings_io.h"
|
#include "files/settings_io.h"
|
||||||
|
#include "util/ObjectsKeeper.hpp"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -38,7 +39,7 @@ public:
|
|||||||
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Engine {
|
class Engine : public util::ObjectsKeeper {
|
||||||
EngineSettings& settings;
|
EngineSettings& settings;
|
||||||
SettingsHandler settingsHandler;
|
SettingsHandler settingsHandler;
|
||||||
EnginePaths* paths;
|
EnginePaths* paths;
|
||||||
|
|||||||
@@ -86,8 +86,6 @@ void MenuScreen::draw(float delta) {
|
|||||||
batch->flush();
|
batch->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool backlight;
|
|
||||||
|
|
||||||
LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
||||||
auto& settings = engine->getSettings();
|
auto& settings = engine->getSettings();
|
||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
@@ -100,8 +98,12 @@ LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
|||||||
worldRenderer = std::make_unique<WorldRenderer>(engine, frontend.get(), controller->getPlayer());
|
worldRenderer = std::make_unique<WorldRenderer>(engine, frontend.get(), controller->getPlayer());
|
||||||
hud = std::make_unique<Hud>(engine, frontend.get(), controller->getPlayer());
|
hud = std::make_unique<Hud>(engine, frontend.get(), controller->getPlayer());
|
||||||
|
|
||||||
|
keepAlive(settings.graphics.backlight.observe([=](bool flag) {
|
||||||
backlight = settings.graphics.backlight.get();
|
controller->getLevel()->chunks->saveAndClear();
|
||||||
|
}));
|
||||||
|
keepAlive(settings.camera.fov.observe([=](double value) {
|
||||||
|
controller->getPlayer()->camera->setFov(glm::radians(value));
|
||||||
|
}));
|
||||||
|
|
||||||
animator = std::make_unique<TextureAnimator>();
|
animator = std::make_unique<TextureAnimator>();
|
||||||
animator->addAnimations(assets->getAnimations());
|
animator->addAnimations(assets->getAnimations());
|
||||||
@@ -163,14 +165,6 @@ void LevelScreen::update(float delta) {
|
|||||||
camera->up
|
camera->up
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: subscribe for setting change
|
|
||||||
EngineSettings& settings = engine->getSettings();
|
|
||||||
controller->getPlayer()->camera->setFov(glm::radians(settings.camera.fov.get()));
|
|
||||||
if (settings.graphics.backlight.get() != backlight) {
|
|
||||||
controller->getLevel()->chunks->saveAndClear();
|
|
||||||
backlight = settings.graphics.backlight.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hud->isPause()) {
|
if (!hud->isPause()) {
|
||||||
controller->getLevel()->getWorld()->updateTimers(delta);
|
controller->getLevel()->getWorld()->updateTimers(delta);
|
||||||
animator->update(delta);
|
animator->update(delta);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "../settings.h"
|
#include "../settings.h"
|
||||||
|
#include "../util/ObjectsKeeper.hpp"
|
||||||
|
|
||||||
class Assets;
|
class Assets;
|
||||||
class Level;
|
class Level;
|
||||||
@@ -16,7 +17,7 @@ class LevelController;
|
|||||||
class TextureAnimator;
|
class TextureAnimator;
|
||||||
|
|
||||||
/// @brief Screen is a mainloop state
|
/// @brief Screen is a mainloop state
|
||||||
class Screen {
|
class Screen : public util::ObjectsKeeper {
|
||||||
protected:
|
protected:
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
std::unique_ptr<Batch2D> batch;
|
std::unique_ptr<Batch2D> batch;
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef UTIL_OBJECTS_KEEPER_HPP_
|
||||||
|
#define UTIL_OBJECTS_KEEPER_HPP_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
class ObjectsKeeper {
|
||||||
|
std::vector<std::shared_ptr<void>> ptrs;
|
||||||
|
public:
|
||||||
|
virtual ~ObjectsKeeper() {}
|
||||||
|
|
||||||
|
virtual void keepAlive(std::shared_ptr<void> ptr) {
|
||||||
|
ptrs.push_back(ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // UTIL_OBJECTS_KEEPER_HPP_
|
||||||
Reference in New Issue
Block a user