settings observers lifecycle
This commit is contained in:
parent
201209887f
commit
5b82b18c6f
@ -4,6 +4,7 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "../delegates.h"
|
||||
@ -30,13 +31,35 @@ public:
|
||||
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 {
|
||||
protected:
|
||||
number_t initial;
|
||||
number_t value;
|
||||
number_t min;
|
||||
number_t max;
|
||||
std::vector<consumer<number_t>> consumers;
|
||||
Observers<number_t> observers;
|
||||
public:
|
||||
NumberSetting(
|
||||
number_t value,
|
||||
@ -63,9 +86,7 @@ public:
|
||||
return;
|
||||
}
|
||||
this->value = value;
|
||||
for (auto& callback : consumers) {
|
||||
callback(value);
|
||||
}
|
||||
observers.notify(value);
|
||||
}
|
||||
|
||||
number_t getMin() const {
|
||||
@ -80,12 +101,12 @@ public:
|
||||
return (value - min) / (max - min);
|
||||
}
|
||||
|
||||
void observe(consumer<number_t> callback) {
|
||||
consumers.push_back(callback);
|
||||
observer_handler observe(consumer<number_t> callback) {
|
||||
return observers.observe(callback);
|
||||
}
|
||||
|
||||
virtual void resetToDefault() override {
|
||||
value = initial;
|
||||
set(initial);
|
||||
}
|
||||
|
||||
virtual std::string toString() const override;
|
||||
@ -101,7 +122,7 @@ protected:
|
||||
integer_t value;
|
||||
integer_t min;
|
||||
integer_t max;
|
||||
std::vector<consumer<integer_t>> consumers;
|
||||
Observers<integer_t> observers;
|
||||
public:
|
||||
IntegerSetting(
|
||||
integer_t value,
|
||||
@ -128,9 +149,7 @@ public:
|
||||
return;
|
||||
}
|
||||
this->value = value;
|
||||
for (auto& callback : consumers) {
|
||||
callback(value);
|
||||
}
|
||||
observers.notify(value);
|
||||
}
|
||||
|
||||
integer_t getMin() const {
|
||||
@ -145,12 +164,12 @@ public:
|
||||
return (value - min) / (max - min);
|
||||
}
|
||||
|
||||
void observe(consumer<integer_t> callback) {
|
||||
consumers.push_back(callback);
|
||||
observer_handler observe(consumer<integer_t> callback) {
|
||||
return observers.observe(callback);
|
||||
}
|
||||
|
||||
virtual void resetToDefault() override {
|
||||
value = initial;
|
||||
set(initial);
|
||||
}
|
||||
|
||||
virtual std::string toString() const override;
|
||||
@ -160,7 +179,7 @@ class FlagSetting : public Setting {
|
||||
protected:
|
||||
bool initial;
|
||||
bool value;
|
||||
std::vector<consumer<bool>> consumers;
|
||||
Observers<bool> observers;
|
||||
public:
|
||||
FlagSetting(
|
||||
bool value,
|
||||
@ -183,17 +202,15 @@ public:
|
||||
return;
|
||||
}
|
||||
this->value = value;
|
||||
for (auto& callback : consumers) {
|
||||
callback(value);
|
||||
}
|
||||
observers.notify(value);
|
||||
}
|
||||
|
||||
void observe(consumer<bool> callback) {
|
||||
consumers.push_back(callback);
|
||||
observer_handler observe(consumer<bool> callback) {
|
||||
return observers.observe(callback);
|
||||
}
|
||||
|
||||
virtual void resetToDefault() override {
|
||||
value = initial;
|
||||
set(initial);
|
||||
}
|
||||
|
||||
virtual std::string toString() const override;
|
||||
|
||||
@ -47,13 +47,13 @@ void addWorldGenerators() {
|
||||
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") {
|
||||
audio::create_channel(name);
|
||||
}
|
||||
setting.observe([=](auto value) {
|
||||
engine->keepAlive(setting.observe([=](auto value) {
|
||||
audio::get_channel(name)->setVolume(value*value);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Engine::Engine(EngineSettings& settings, EnginePaths* paths)
|
||||
@ -64,11 +64,11 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths)
|
||||
throw initialize_error("could not initialize window");
|
||||
}
|
||||
audio::initialize(settings.audio.enabled);
|
||||
create_channel("master", settings.audio.volumeMaster);
|
||||
create_channel("regular", settings.audio.volumeRegular);
|
||||
create_channel("music", settings.audio.volumeMusic);
|
||||
create_channel("ambient", settings.audio.volumeAmbient);
|
||||
create_channel("ui", settings.audio.volumeUI);
|
||||
create_channel(this, "master", settings.audio.volumeMaster);
|
||||
create_channel(this, "regular", settings.audio.volumeRegular);
|
||||
create_channel(this, "music", settings.audio.volumeMusic);
|
||||
create_channel(this, "ambient", settings.audio.volumeAmbient);
|
||||
create_channel(this, "ui", settings.audio.volumeUI);
|
||||
|
||||
auto resdir = paths->getResources();
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "content/PacksManager.h"
|
||||
#include "files/engine_paths.h"
|
||||
#include "files/settings_io.h"
|
||||
#include "util/ObjectsKeeper.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
@ -38,7 +39,7 @@ public:
|
||||
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
class Engine {
|
||||
class Engine : public util::ObjectsKeeper {
|
||||
EngineSettings& settings;
|
||||
SettingsHandler settingsHandler;
|
||||
EnginePaths* paths;
|
||||
|
||||
@ -86,8 +86,6 @@ void MenuScreen::draw(float delta) {
|
||||
batch->flush();
|
||||
}
|
||||
|
||||
static bool backlight;
|
||||
|
||||
LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
|
||||
auto& settings = engine->getSettings();
|
||||
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());
|
||||
hud = std::make_unique<Hud>(engine, frontend.get(), controller->getPlayer());
|
||||
|
||||
|
||||
backlight = settings.graphics.backlight.get();
|
||||
keepAlive(settings.graphics.backlight.observe([=](bool flag) {
|
||||
controller->getLevel()->chunks->saveAndClear();
|
||||
}));
|
||||
keepAlive(settings.camera.fov.observe([=](double value) {
|
||||
controller->getPlayer()->camera->setFov(glm::radians(value));
|
||||
}));
|
||||
|
||||
animator = std::make_unique<TextureAnimator>();
|
||||
animator->addAnimations(assets->getAnimations());
|
||||
@ -163,14 +165,6 @@ void LevelScreen::update(float delta) {
|
||||
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()) {
|
||||
controller->getLevel()->getWorld()->updateTimers(delta);
|
||||
animator->update(delta);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include "../settings.h"
|
||||
#include "../util/ObjectsKeeper.hpp"
|
||||
|
||||
class Assets;
|
||||
class Level;
|
||||
@ -16,7 +17,7 @@ class LevelController;
|
||||
class TextureAnimator;
|
||||
|
||||
/// @brief Screen is a mainloop state
|
||||
class Screen {
|
||||
class Screen : public util::ObjectsKeeper {
|
||||
protected:
|
||||
Engine* engine;
|
||||
std::unique_ptr<Batch2D> batch;
|
||||
|
||||
19
src/util/ObjectsKeeper.hpp
Normal file
19
src/util/ObjectsKeeper.hpp
Normal file
@ -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_
|
||||
Loading…
x
Reference in New Issue
Block a user