[nostalgia/studio] Fix TileSheetEditor to switch to appropriate subsheet on undo/redo

This commit is contained in:
2022-05-18 21:15:11 -05:00
parent 71f6364ea3
commit 6854e658a0
12 changed files with 158 additions and 52 deletions
+71 -15
View File
@@ -5,6 +5,7 @@
#pragma once
#include <ox/model/typenamecatcher.hpp>
#include <ox/event/signal.hpp>
#include <ox/fs/fs.hpp>
#include <ox/std/hashmap.hpp>
#include <ox/std/utility.hpp>
@@ -27,6 +28,8 @@ struct AssetContainer {
mutable int m_references = 0;
public:
ox::Signal<ox::Error()> updated;
template<class... Args>
explicit constexpr AssetContainer(Args&&... args): m_obj(ox::forward<Args>(args)...) {
}
@@ -39,6 +42,14 @@ struct AssetContainer {
return &m_obj;
}
constexpr void set(T &&val) {
m_obj = std::move(val);
}
constexpr void set(const T &val) {
m_obj = val;
}
protected:
constexpr void incRefs() const noexcept {
++m_references;
@@ -55,27 +66,20 @@ struct AssetContainer {
};
template<typename T>
class AssetRef {
class AssetRef: public ox::SignalHandler {
private:
const AssetContainer<T> *m_ctr = nullptr;
public:
explicit constexpr AssetRef(const AssetContainer<T> *c = nullptr) noexcept: m_ctr(c) {
}
ox::Signal<ox::Error()> updated;
constexpr AssetRef(const AssetRef &h) noexcept {
m_ctr = h.m_ctr;
if (m_ctr) {
m_ctr->incRefs();
}
}
explicit constexpr AssetRef(const AssetContainer<T> *c = nullptr) noexcept;
constexpr AssetRef(AssetRef &&h) noexcept {
m_ctr = h.m_ctr;
h.m_ctr = nullptr;
}
constexpr AssetRef(const AssetRef &h) noexcept;
~AssetRef() noexcept {
constexpr AssetRef(AssetRef &&h) noexcept;
~AssetRef() noexcept override {
if (m_ctr) {
m_ctr->decRefs();
}
@@ -103,8 +107,10 @@ class AssetRef {
}
if (m_ctr) {
m_ctr->decRefs();
oxIgnoreError(m_ctr->updated.disconnectObject(this));
}
m_ctr = h.m_ctr;
m_ctr->updated.connect(&updated, &ox::Signal<ox::Error()>::emitCheckError);
if (m_ctr) {
m_ctr->incRefs();
}
@@ -115,7 +121,12 @@ class AssetRef {
if (this == &h) {
return *this;
}
if (m_ctr) {
m_ctr->decRefs();
oxIgnoreError(m_ctr->updated.disconnectObject(this));
}
m_ctr = h.m_ctr;
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
h.m_ctr = nullptr;
return *this;
}
@@ -124,8 +135,36 @@ class AssetRef {
return m_ctr;
}
private:
constexpr ox::Error emitUpdated() const noexcept {
updated.emit();
return OxError(0);
}
};
template<typename T>
constexpr AssetRef<T>::AssetRef(const AssetContainer<T> *c) noexcept: m_ctr(c) {
if (c) {
c->updated.connect(this, &AssetRef::emitUpdated);
}
}
template<typename T>
constexpr AssetRef<T>::AssetRef(const AssetRef &h) noexcept {
m_ctr = h.m_ctr;
if (m_ctr) {
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
m_ctr->incRefs();
}
}
template<typename T>
constexpr AssetRef<T>::AssetRef(AssetRef &&h) noexcept {
m_ctr = h.m_ctr;
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
h.m_ctr = nullptr;
}
class AssetManager {
private:
class AssetTypeManagerBase {
@@ -148,7 +187,24 @@ class AssetManager {
}
ox::Result<AssetRef<T>> setAsset(const ox::String &path, const T &obj) noexcept {
auto &p = m_cache[path] = ox::make_unique<AssetContainer<T>>(obj);
auto &p = m_cache[path];
if (!p) {
p = ox::make_unique<AssetContainer<T>>(obj);
} else {
p->set(obj);
p->updated.emit();
}
return AssetRef<T>(p.get());
}
ox::Result<AssetRef<T>> setAsset(const ox::String &path, T &&obj) noexcept {
auto &p = m_cache[path];
if (!p) {
p = ox::make_unique<AssetContainer<T>>(obj);
} else {
p->set(std::move(obj));
p->updated.emit();
}
return AssetRef<T>(p.get());
}