Files
Renderive/web_server/app/Gallery_Controls.h
T
2026-08-12 02:02:39 +08:00

88 lines
2.5 KiB
C++

#pragma once
#include "Gallery_Renderables.h"
#include <nlohmann/json.hpp>
#include <functional>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
namespace renderive::web {
class Gallery_Controls final {
public:
using Json = nlohmann::json;
template <class Object>
void add(Object& object) {
const auto descriptor = adminive::Type_Descriptor<Object>::get();
add(descriptor.name(), descriptor.label(), object);
}
template <class Object>
void add(std::string id, Object& object) {
add(std::move(id), adminive::Type_Descriptor<Object>::get().label(), object);
}
private:
template <class Object>
void add(std::string id, std::string title, Object& object) {
using Model = adminive::Object_Model_Type<Object>;
auto* target = &object;
entries_.push_back({
std::move(id), std::move(title),
[target] {
return Json{
{"descriptor", adminive::to_descriptor_json<Json, Object>()},
{"view", adminive::to_view_json<Json, Model>(
adminive::describe_edit_view<Model>())},
{"data", adminive::to_frontend_json<Json>(*target)}
};
},
[target](const Json& patch) {
return adminive::apply_frontend_patch<Json>(*target, patch);
}
});
}
public:
[[nodiscard]] Json resources() const {
Json result = Json::array();
for (const auto& entry : entries_) {
Json resource = entry.resource();
resource["target"] = entry.id;
resource["view"]["title"] = entry.title;
result.push_back(std::move(resource));
}
return result;
}
[[nodiscard]] adminive::Update_Result apply(std::string_view target,
const Json& patch) const {
for (const auto& entry : entries_) {
if (entry.id == target)
return entry.apply(patch);
}
adminive::Update_Result result;
result.success = false;
result.message = "unknown gallery control target: " + std::string(target);
return result;
}
private:
struct Entry {
std::string id;
std::string title;
std::function<Json()> resource;
std::function<adminive::Update_Result(const Json&)> apply;
};
std::vector<Entry> entries_;
};
} // namespace renderive::web