Checkpoint 2: integrate native Editor, MCP, gameplay builds and standalone export
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
#include <faset/core/json.hpp>
|
||||
#include <faset/core/error.hpp>
|
||||
#include <faset/core/json.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace faset::authoring {
|
||||
class SchemaRegistry {
|
||||
public:
|
||||
public:
|
||||
void register_schema(const Json& schema);
|
||||
void register_schemas(const Json& schemas);
|
||||
bool contains(const std::string& type) const;
|
||||
@@ -18,29 +18,43 @@ public:
|
||||
void validate_component(const Json& component) const;
|
||||
Json migrate_component(const Json& component) const;
|
||||
void add_migration(const std::string& type, int from_version, Json field_rules);
|
||||
private:
|
||||
std::map<std::string,Json> schemas_;
|
||||
std::map<std::pair<std::string,int>,Json> migrations_;
|
||||
|
||||
private:
|
||||
std::map<std::string, Json> schemas_;
|
||||
std::map<std::pair<std::string, int>, Json> migrations_;
|
||||
};
|
||||
|
||||
template<class T> class TypeRegistration {
|
||||
public:
|
||||
TypeRegistration(SchemaRegistry& registry, std::string id, std::string name, int version=1)
|
||||
: registry_(registry),schema_{{"id",std::move(id)},{"name",std::move(name)},{"version",version},{"fields",Json::object()}} {}
|
||||
template<class Value>
|
||||
TypeRegistration& field(std::string id, std::string name, Value T::*member, Value default_value,
|
||||
std::string kind, Json constraints=Json::object()) {
|
||||
template <class T> class TypeRegistration {
|
||||
public:
|
||||
TypeRegistration(SchemaRegistry& registry, std::string id, std::string name, int version = 1)
|
||||
: registry_(registry), schema_{{"id", std::move(id)},
|
||||
{"name", std::move(name)},
|
||||
{"version", version},
|
||||
{"fields", Json::object()}} {}
|
||||
template <class Value>
|
||||
TypeRegistration& field(std::string id, std::string name, Value T::* member,
|
||||
Value default_value, std::string kind,
|
||||
Json constraints = Json::object()) {
|
||||
static_assert(std::is_member_object_pointer_v<decltype(member)>);
|
||||
require(!schema_["fields"].contains(id),"schema.duplicate_field","Duplicate stable FieldId");
|
||||
require(!schema_["fields"].contains(id), "schema.duplicate_field",
|
||||
"Duplicate stable FieldId");
|
||||
// Converting the typed default checks supported JSON serialization at compile time.
|
||||
Json descriptor={{"id",id},{"name",std::move(name)},{"type",std::move(kind)},{"default",Json(default_value)}};
|
||||
descriptor.update(constraints); schema_["fields"][id]=std::move(descriptor); return *this;
|
||||
Json descriptor = {{"id", id},
|
||||
{"name", std::move(name)},
|
||||
{"type", std::move(kind)},
|
||||
{"default", Json(default_value)}};
|
||||
descriptor.update(constraints);
|
||||
schema_["fields"][id] = std::move(descriptor);
|
||||
return *this;
|
||||
}
|
||||
void commit() { registry_.register_schema(schema_); }
|
||||
private:
|
||||
void commit() {
|
||||
registry_.register_schema(schema_);
|
||||
}
|
||||
|
||||
private:
|
||||
SchemaRegistry& registry_;
|
||||
Json schema_;
|
||||
};
|
||||
SchemaRegistry builtin_schemas();
|
||||
void validate_field(const Json& value,const Json& descriptor);
|
||||
}
|
||||
void validate_field(const Json& value, const Json& descriptor);
|
||||
} // namespace faset::authoring
|
||||
|
||||
@@ -3,47 +3,58 @@
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace faset::authoring {
|
||||
Json make_scene(std::string name,int dimension=3);
|
||||
Json make_entity(const SchemaRegistry& schemas,std::string name,const std::string& parent="");
|
||||
void validate_scene(const Json& scene,const SchemaRegistry& schemas);
|
||||
Json make_scene(std::string name, int dimension = 3);
|
||||
Json make_entity(const SchemaRegistry& schemas, std::string name, const std::string& parent = "");
|
||||
void validate_scene(const Json& scene, const SchemaRegistry& schemas);
|
||||
|
||||
class AuthoringService {
|
||||
public:
|
||||
explicit AuthoringService(std::filesystem::path project_root,SchemaRegistry schemas=builtin_schemas());
|
||||
Json create(std::string name,int dimension=3);
|
||||
Json open(const std::filesystem::path& relative,bool recover=false);
|
||||
public:
|
||||
explicit AuthoringService(std::filesystem::path project_root,
|
||||
SchemaRegistry schemas = builtin_schemas());
|
||||
Json create(std::string name, int dimension = 3);
|
||||
Json open(const std::filesystem::path& relative, bool recover = false);
|
||||
Json query(const std::string& document) const;
|
||||
Json documents() const;
|
||||
Json transact(const std::string& document,std::uint64_t expected_revision,const Json& operations,const std::string& idempotency_key="");
|
||||
Json undo(const std::string& document,std::uint64_t expected_revision);
|
||||
Json redo(const std::string& document,std::uint64_t expected_revision);
|
||||
Json save(const std::string& document,const std::filesystem::path& relative={});
|
||||
Json transact(const std::string& document, std::uint64_t expected_revision,
|
||||
const Json& operations, const std::string& idempotency_key = "");
|
||||
Json undo(const std::string& document, std::uint64_t expected_revision);
|
||||
Json redo(const std::string& document, std::uint64_t expected_revision);
|
||||
Json save(const std::string& document, const std::filesystem::path& relative = {});
|
||||
Json recovery_documents() const;
|
||||
const SchemaRegistry& schemas() const {return schemas_;}
|
||||
Json recover(const std::string& document,
|
||||
std::optional<std::uint64_t> expected_revision = std::nullopt);
|
||||
const SchemaRegistry& schemas() const {
|
||||
return schemas_;
|
||||
}
|
||||
void register_schemas(const Json& manifest);
|
||||
const std::filesystem::path& root() const {return root_;}
|
||||
private:
|
||||
void replace_external_schemas(const Json& manifest);
|
||||
const std::filesystem::path& root() const {
|
||||
return root_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct State {
|
||||
Json data;
|
||||
std::uint64_t revision=0;
|
||||
std::uint64_t revision = 0;
|
||||
std::filesystem::path path;
|
||||
std::string saved_hash,disk_hash;
|
||||
std::vector<Json> undo,redo;
|
||||
std::map<std::string,std::pair<std::string,Json>> requests;
|
||||
std::string saved_hash, disk_hash;
|
||||
std::vector<Json> undo, redo;
|
||||
std::map<std::string, std::pair<std::string, Json>> requests;
|
||||
};
|
||||
Json summary(const State& state,bool include_data=true) const;
|
||||
Json summary(const State& state, bool include_data = true) const;
|
||||
State& state(const std::string& document);
|
||||
const State& state(const std::string& document) const;
|
||||
void journal(const State& state) const;
|
||||
void apply(Json& scene,const Json& operation);
|
||||
Json history(const std::string& document,std::uint64_t revision,bool redo);
|
||||
void apply(Json& scene, const Json& operation);
|
||||
Json history(const std::string& document, std::uint64_t revision, bool redo);
|
||||
std::filesystem::path root_;
|
||||
SchemaRegistry schemas_;
|
||||
std::map<std::string,State> documents_;
|
||||
std::map<std::string, State> documents_;
|
||||
mutable std::recursive_mutex mutex_;
|
||||
};
|
||||
}
|
||||
} // namespace faset::authoring
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
#include <string>
|
||||
|
||||
namespace faset::authoring {
|
||||
struct ResolvedScene {Json scene;Json conflicts=Json::array();};
|
||||
using SceneLoader=std::function<Json(const std::string&)>;
|
||||
struct ResolvedScene {
|
||||
Json scene;
|
||||
Json conflicts = Json::array();
|
||||
};
|
||||
using SceneLoader = std::function<Json(const std::string&)>;
|
||||
// Source documents are immutable inputs. Conflicting records stay in the authoring file.
|
||||
ResolvedScene resolve_templates(const Json& scene,const SchemaRegistry& schemas,const SceneLoader& loader);
|
||||
}
|
||||
ResolvedScene resolve_templates(const Json& scene, const SchemaRegistry& schemas,
|
||||
const SceneLoader& loader);
|
||||
} // namespace faset::authoring
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <faset/core/json.hpp>
|
||||
#include <string>
|
||||
namespace faset::authoring {
|
||||
// Reparents authored TRS while optionally preserving the complete world transform.
|
||||
// Non-invertible parents and transforms requiring shear are rejected atomically.
|
||||
void reparent_entity(Json& scene, const std::string& entity, const Json& parent, bool keep_world);
|
||||
} // namespace faset::authoring
|
||||
Reference in New Issue
Block a user