Cogs.Core
FieldCommands.h
1#pragma once
2
3#include "EditorCommand.h"
4
5namespace Cogs::Core
6{
7 struct FieldInfo
8 {
9 Reflection::TypeId componentId;
10 Reflection::FieldId fieldId;
11 };
12
13 template<typename T>
15 {
16 SetFieldCommand(EditorState * state, EntityIds entityIds, FieldInfo fieldInfo, T fieldData)
17 : EditorCommand(state, state->context), entityIds(entityIds), fieldInfo(fieldInfo), fieldData(fieldData)
18 {
19 }
20
21 void close() override
22 {
23 // Don't close field commands. Allow merging several
24 }
25
26 void apply() override
27 {
28 for (auto & id : entityIds) {
29 auto entity = context->store->getEntityPtr(id);
30 auto component = entity->getComponent(fieldInfo.componentId);
31 auto & fieldType = Reflection::TypeDatabase::getType(fieldInfo.componentId);
32 auto field = fieldType.getField(fieldInfo.fieldId);
33 auto fieldPtr = field->template getPtr<T>(component);
34
35 previousDatas.push_back(*fieldPtr);
36
37 *fieldPtr = fieldData;
38
39 component->setFieldChanged(fieldInfo.fieldId);
40 }
41 }
42
43 void undo() override
44 {
45 for (size_t i = 0; i < entityIds.size(); ++i) {
46 auto entity = context->store->getEntityPtr(entityIds[i]);
47 auto component = entity->getComponent(fieldInfo.componentId);
48 auto & fieldType = Reflection::TypeDatabase::getType(fieldInfo.componentId);
49 auto field = fieldType.getField(fieldInfo.fieldId);
50 auto fieldPtr = field->template getPtr<T>(component);
51
52 *fieldPtr = previousDatas[i];
53
54 component->setFieldChanged(fieldInfo.fieldId);
55 }
56
57 previousDatas.clear();
58 }
59
60 bool mergeWith(const EditorCommand * command) override
61 {
62 auto setFieldCommand = dynamic_cast<const SetFieldCommand<T> *>(command);
63
64 if (!setFieldCommand) {
65 return false;
66 }
67
68 if (entityIds != setFieldCommand->entityIds) {
69 return false;
70 }
71
72 if (fieldInfo.componentId != setFieldCommand->fieldInfo.componentId || fieldInfo.fieldId != setFieldCommand->fieldInfo.fieldId) {
73 return false;
74 }
75
76 fieldData = setFieldCommand->fieldData;
77
78 return true;
79 }
80
81 private:
82 EntityIds entityIds;
83 FieldInfo fieldInfo;
84 T fieldData;
85
86 std::vector<T> previousDatas;
87 };
88}
T * getComponent() const
Get a pointer to the first component implementing the given type in the entity.
Definition: Entity.h:35
class EntityStore * store
Entity store.
Definition: Context.h:231
ComponentModel::Entity * getEntityPtr(const EntityId entityId)
Get a raw pointer to the entity with the given id.
static const Type & getType()
Get the Type of the given template argument.
Definition: TypeDatabase.h:168
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
uint16_t TypeId
Built in type used to uniquely identify a single type instance.
Definition: Name.h:48
uint16_t FieldId
Type used to index fields.
Definition: Name.h:54
Base class for Cogs Editor commands.
Definition: EditorCommand.h:19
bool mergeWith(const EditorCommand *command) override
Definition: FieldCommands.h:60
void close() override
Close command, i.e. prevent merging with another command.
Definition: FieldCommands.h:21
void apply() override
Run the command.
Definition: FieldCommands.h:26