载入中...
搜索中...
未找到
AvatarEditingCommands.cpp
浏览该文件的文档.
2
4
6
8namespace {
9
10const editing::Value* field(const editing::Value& value, const char* key) {
11 const auto* object = value.getIf<editing::Value::Object>();
12 if (!object) return nullptr;
13 const auto found = object->find(key);
14 return found == object->end() ? nullptr : &found->second;
15}
16
17const std::string* stringField(const editing::Value& value, const char* key) {
18 const editing::Value* entry = field(value, key);
19 return entry ? entry->getIf<std::string>() : nullptr;
20}
21
22editing::SelectionSnapshot selectionFor(editing::IEditableTarget& target, const std::string& item,
23 const std::string& type) {
25 selection.channel = "avatar";
28 row.target = editing::TargetId(target.targetId());
29 row.item = editing::StableId(item);
30 row.type = type;
31 selection.items.push_back(row);
32 selection.primary = row;
33 return selection;
34}
35
37 return dynamic_cast<AvatarDocumentTarget*>(&target);
38}
39
42 auto* properties = static_cast<editing::IPropertyProvider*>(
43 target.queryCapability(editing::CapabilityId("eve.editor.target.avatar-properties")));
44 if (!properties)
47 const auto* item = stringField(request.payload, "item");
48 const auto* type = stringField(request.payload, "type");
49 const auto* path = stringField(request.payload, "path");
50 const editing::Value* value = field(request.payload, "value");
51 if (!properties || !item || !type || !path || !value)
52 return eve::editing::failed<editing::CommandPlan>(
53 editing::Status::Rejected, editing::RuleId("avatar.editing.property-payload"),
54 "Avatar property requires a property target, item, type, path and value");
55 auto operation = properties->makeSet(selectionFor(target, *item, *type), editing::PropertyPath(*path), *value,
57 if (!operation.ok())
58 return eve::editing::failed<editing::CommandPlan>(operation.code(),
59 editing::RuleId("avatar.editing.property-operation"),
60 "Avatar target rejected the property value");
62 plan.operations.push_back(std::move(operation.value()));
63 plan.summary = editing::Value::Object{{"item", *item}, {"path", *path}};
64 return eve::editing::applied<editing::CommandPlan>(std::move(plan));
65}
66
69 auto* avatar = asAvatar(target);
70 const auto* id = stringField(request.payload, "id");
71 const auto* name = stringField(request.payload, "name");
72 const auto* texture = stringField(request.payload, "texture");
73 if (!avatar || !id || !name || !texture)
74 return eve::editing::failed<editing::CommandPlan>(
75 editing::Status::Rejected, editing::RuleId("avatar.editing.layer-payload"),
76 "Avatar layer create requires a document target, id, name and texture");
79 layer.name = *name;
80 layer.textureAsset = *texture;
81 auto operation = avatar->makeCreateLayer(layer);
82 if (!operation.ok())
83 return eve::editing::failed<editing::CommandPlan>(
84 operation.code(), editing::RuleId("avatar.editing.layer-operation"), "Avatar target rejected the layer");
86 plan.operations.push_back(std::move(operation.value()));
87 plan.summary = editing::Value::Object{{"id", *id}, {"name", *name}};
88 return eve::editing::applied<editing::CommandPlan>(std::move(plan));
89}
90
93 auto* avatar = asAvatar(target);
94 const auto* id = stringField(request.payload, "id");
95 const auto* name = stringField(request.payload, "name");
96 if (!avatar || !id || !name)
97 return eve::editing::failed<editing::CommandPlan>(
98 editing::Status::Rejected, editing::RuleId("avatar.editing.parameter-payload"),
99 "Avatar parameter create requires a document target, id and name");
100 AvatarParameterValue parameter;
101 parameter.id = editing::ObjectId(*id);
102 parameter.name = *name;
103 auto operation = avatar->makeCreateParameter(parameter);
104 if (!operation.ok())
105 return eve::editing::failed<editing::CommandPlan>(operation.code(),
106 editing::RuleId("avatar.editing.parameter-operation"),
107 "Avatar target rejected the parameter");
109 plan.operations.push_back(std::move(operation.value()));
110 plan.summary = editing::Value::Object{{"id", *id}, {"name", *name}};
111 return eve::editing::applied<editing::CommandPlan>(std::move(plan));
112}
113
114editing::Result<void> registerOne(editing::IEditingCommandRegistry& registry, const char* id, const char* display,
118 descriptor.ownerModule = "avatar_editing";
119 descriptor.displayName = display;
120 descriptor.category = "Avatar";
121 descriptor.automationAllowed = true;
122 return registry.registerPlannedCommand(std::move(descriptor), std::move(planner));
123}
124
125} // namespace
126
128 auto registered = registerOne(registry, "avatar.property.set.v1", "Set avatar property", propertySet);
129 if (!registered.ok()) return registered;
130 registered = registerOne(registry, "avatar.layer.create.v1", "Create avatar layer", layerCreate);
131 if (!registered.ok()) {
132 registry.unregisterOwner("avatar_editing").ignore("avatar command registration rollback");
133 return registered;
134 }
135 registered = registerOne(registry, "avatar.parameter.create.v1", "Create avatar parameter", parameterCreate);
136 if (!registered.ok())
137 registry.unregisterOwner("avatar_editing").ignore("avatar command registration rollback");
138 return registered;
139}
140
141} // namespace eve::avatar_editing
LogicalId target
ActionParameterOperation operation
double value
std::string descriptor
const GltfImportRequest & request
std::uint32_t key
std::map< std::string, PropertyRule > properties
std::string name
TileLayer * layer
std::string path
Definition PlayHost.cpp:110
bool found
Move-only operation result carrying either a value or Status.
Definition Result.h:155
UUID-backed identifier adapter for legacy textual boundaries.
Definition Identity.h:314
Revisioned image/Live2D/VRoid Avatar authoring asset.
IEditableTarget public API.
Lower-layer registration boundary implemented by an editor or runtime editing host.
virtual Result< void > registerPlannedCommand(EditingCommandDescriptor descriptor, EditingCommandPlanner planner)=0
Register or replace one domain-owned planned command.
virtual Result< std::size_t > unregisterOwner(const std::string &ownerModule)=0
Remove every command registered by one domain module.
UI-independent property access for an immutable selection snapshot.
static CapabilityId editingCapabilityId()
Stable capability identity for generic property editing.
Dotted property path (layout.size) compared and persisted as text.
Definition EditingIds.h:78
Deterministic owning value tree shared by authoring hosts.
std::map< std::string, Value > Object
const T * getIf() const
Return an immediately borrowed typed value.
editing::Result< void > registerEditingCommands(editing::IEditingCommandRegistry &registry)
Register Avatar-owned property and structure commands with a generic editing host.
StrongId< TargetIdTag > TargetId
Definition EditingIds.h:57
StrongId< ObjectIdTag > ObjectId
Definition EditingIds.h:65
std::function< Result< CommandPlan >(IEditableTarget &, const CommandRequest &)> EditingCommandPlanner
Side-effect-free planner invoked with the resolved target.
StrongId< StableIdTag > StableId
Definition EditingIds.h:64
StrongId< CommandIdTag > CommandId
Definition EditingIds.h:58
Stable image layer in an Avatar asset.
Reflected Avatar parameter and its initial value.
CommandPlan public API.
std::vector< DomainOperation > operations
CommandRequest public API.
Domain-owned metadata for one planned editing command.
SelectionItem public API.
SelectionSnapshot public API.
std::vector< SelectionItem > items
std::optional< SelectionItem > primary
NodeType type
Definition Widget.h:16