Я много лет боролся с проблемой в поисках элегантного решения, но мне так и не удалось его найти. Поэтому я решил, что наконец-то получу обратную связь от сообщества.
Я хочу разработать следующую систему:
Представьте себе слои, расположенные поверх друг друга. друг друга — обычно всего 2 или 3, но их может достигать 50 или 100. Каждый слой содержит объекты. Для упрощения представим, что эти объекты представляют собой геометрические формы, такие как сферы, конусы, торы и т. д., определяемые набором свойств. Например, у сферы есть радиус и центр, у конуса есть диаметр основания и высота, определяющая расстояние от основания до вершины, а у тора есть внутренний и внешний радиусы и т. д.
Первый слой может состоять из таких объектов. Затем у меня есть слой сверху, где:
- Может быть больше объектов (новые объекты).
- Переопределения существуют для параметров, связанных с объектами в более глубоких слоях (слоях ниже текущего слоя).
- Добавления всех объектов, определенных во всех слоях.
- Устранение переопределений.
Вот базовая реализация, иллюстрирующая концепцию:
Код: Выделить всё
#include
#include
#include
#include
#include
#include
struct Vec3 {
float x, y, z;
};
using ParamValue = std::variant;
using ParamMap = std::unordered_map;
struct Object {
std::string type;
ParamMap params;
void* uid; // use pointer as UID for simplicity
explicit Object(std::string type) : type(std::move(type)), uid(this) {}
virtual ~Object() = default;
};
struct Sphere : Object {
Sphere() : Object("Sphere") {
params["radius"] = 0.5f;
params["center"] = Vec3{0, 0, 0};
}
};
struct Torus : Object {
Torus() : Object("Torus") {
params["outer_radius"] = 1.0f;
params["inner_radius"] = 0.4f;
}
};
struct Override {
void* objectUID;
ParamMap overrides;
};
struct Layer {
std::vector objects;
std::vector overrides;
};
void applyOverrides(Object& object, const ParamMap& overrides) {
for (const auto& override : overrides) {
object.params[override.first] = override.second;
}
}
std::vector Flatten(const std::vector& layers) {
std::vector flattenedObjects;
std::unordered_map objectUIDToIndexMap;
for (const auto& layer : layers) {
for (const auto& obj : layer.objects) {
flattenedObjects.push_back(std::make_unique(*obj));
objectUIDToIndexMap[obj->uid] = flattenedObjects.size() - 1;
}
for (const auto& override : layer.overrides) {
if (objectUIDToIndexMap.find(override.objectUID) != objectUIDToIndexMap.end()) {
applyOverrides(*flattenedObjects[objectUIDToIndexMap[override.objectUID]], override.overrides);
}
}
}
return flattenedObjects;
}
int main() {
Layer layer1;
auto sphere = std::make_unique();
void* sphereUID = sphere->uid; // Capture the UID of the sphere for override
layer1.objects.push_back(std::move(sphere));
Layer layer2;
auto torus = std::make_unique();
layer2.objects.push_back(std::move(torus));
Override sphereRadiusOverride;
sphereRadiusOverride.objectUID = sphereUID; // Use sphere's UID for targeting
sphereRadiusOverride.overrides["radius"] = 0.75f; // New radius value
layer2.overrides.push_back(std::move(sphereRadiusOverride));
std::vector layers;
layers.push_back(std::move(layer1));
layers.push_back(std::move(layer2));
auto flattenedView = Flatten(layers);
for (const auto& obj : flattenedView) {
std::cout
Источник: [url]https://stackoverflow.com/questions/78154832/seeking-an-elegant-solution-for-layered-object-management-and-parameter-override[/url]
Мобильная версия