feat: add ObjectRef for scene loading to not rely on runtime id's
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <destrum/ObjectModel/ObjectId.h>
|
||||
#include <destrum/ObjectModel/ObjectRef.h>
|
||||
|
||||
class InteractableButton final : public Interactable {
|
||||
public:
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
|
||||
nlohmann::json Serialize() const override;
|
||||
void Deserialize(const nlohmann::json& data) override;
|
||||
void ResolveReferences(const ObjectMap& objects) override;
|
||||
void ImGuiInspector() override;
|
||||
|
||||
[[nodiscard]] std::size_t GetColorIndex() const { return m_ColorIndex; }
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
// Every Activatable on a target object is activated when the button is pressed
|
||||
void AddTarget(const GameObject& target);
|
||||
void RemoveTarget(ObjectId target);
|
||||
[[nodiscard]] const std::vector<ObjectId>& GetTargets() const { return m_Targets; }
|
||||
[[nodiscard]] const std::vector<ObjectRef>& GetTargets() const { return m_Targets; }
|
||||
|
||||
private:
|
||||
void ApplyColor();
|
||||
@@ -39,7 +40,7 @@ private:
|
||||
std::size_t m_ColorIndex{0};
|
||||
int m_PressCount{0};
|
||||
bool m_CycleColors{true};
|
||||
std::vector<ObjectId> m_Targets;
|
||||
std::vector<ObjectRef> m_Targets;
|
||||
};
|
||||
|
||||
#endif // LIGHTKEEPER_INTERACTABLEBUTTON_H
|
||||
|
||||
@@ -52,15 +52,16 @@ void InteractableButton::Interact(GameObject& interactor)
|
||||
|
||||
void InteractableButton::AddTarget(const GameObject& target)
|
||||
{
|
||||
if (target.GetId() == InvalidObjectId || std::ranges::find(m_Targets, target.GetId()) != m_Targets.end()) {
|
||||
const ObjectRef ref(target);
|
||||
if (!ref.IsSet() || std::ranges::find(m_Targets, ref) != m_Targets.end()) {
|
||||
return;
|
||||
}
|
||||
m_Targets.push_back(target.GetId());
|
||||
m_Targets.push_back(ref);
|
||||
}
|
||||
|
||||
void InteractableButton::RemoveTarget(ObjectId target)
|
||||
{
|
||||
std::erase(m_Targets, target);
|
||||
std::erase(m_Targets, ObjectRef(target));
|
||||
}
|
||||
|
||||
void InteractableButton::ActivateTargets(GameObject& interactor)
|
||||
@@ -70,10 +71,10 @@ void InteractableButton::ActivateTargets(GameObject& interactor)
|
||||
return;
|
||||
}
|
||||
|
||||
for (const ObjectId targetId : m_Targets) {
|
||||
GameObject* target = scene->FindGameObject(targetId);
|
||||
for (const ObjectRef& targetRef : m_Targets) {
|
||||
GameObject* target = targetRef.Get(*scene);
|
||||
if (target == nullptr) {
|
||||
spdlog::warn("{} targets object {} which no longer exists", GetGameObject()->GetName(), targetId);
|
||||
spdlog::warn("{} targets object {} which no longer exists", GetGameObject()->GetName(), targetRef.GetId());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -122,7 +123,19 @@ void InteractableButton::Deserialize(const nlohmann::json& data)
|
||||
m_ColorIndex = data.value("colorIndex", m_ColorIndex) % ButtonColors.size();
|
||||
m_CycleColors = data.value("cycleColors", m_CycleColors);
|
||||
m_PressCount = data.value("pressCount", m_PressCount);
|
||||
m_Targets = data.value("targets", std::vector<ObjectId>{});
|
||||
m_Targets = data.value("targets", std::vector<ObjectRef>{});
|
||||
}
|
||||
|
||||
void InteractableButton::ResolveReferences(const ObjectMap& objects)
|
||||
{
|
||||
std::erase_if(m_Targets, [&](ObjectRef& target) {
|
||||
const ObjectId fileId = target.GetId();
|
||||
if (!target.Resolve(objects)) {
|
||||
spdlog::warn("{} targets object {} which is not in the scene file, dropping it", GetGameObject()->GetName(), fileId);
|
||||
return true;
|
||||
}
|
||||
return !target.IsSet();
|
||||
});
|
||||
}
|
||||
|
||||
void InteractableButton::ImGuiInspector()
|
||||
@@ -149,8 +162,9 @@ void InteractableButton::DrawTargetsInspector()
|
||||
}
|
||||
|
||||
std::optional<ObjectId> targetToRemove;
|
||||
for (const ObjectId targetId : m_Targets) {
|
||||
const GameObject* target = scene->FindGameObject(targetId);
|
||||
for (const ObjectRef& targetRef : m_Targets) {
|
||||
const ObjectId targetId = targetRef.GetId();
|
||||
const GameObject* target = targetRef.Get(*scene);
|
||||
ImGui::PushID(static_cast<int>(targetId));
|
||||
if (ImGui::SmallButton("x")) {
|
||||
targetToRemove = targetId;
|
||||
@@ -170,7 +184,7 @@ void InteractableButton::DrawTargetsInspector()
|
||||
if (ImGui::BeginCombo("##AddTarget", "Add target...")) {
|
||||
for (const auto& object : scene->GetObjects()) {
|
||||
const bool alreadyTargeted = object != nullptr &&
|
||||
std::ranges::find(m_Targets, object->GetId()) != m_Targets.end();
|
||||
std::ranges::find(m_Targets, ObjectRef(*object)) != m_Targets.end();
|
||||
if (object == nullptr || object.get() == GetGameObject() || alreadyTargeted ||
|
||||
object->GetComponent<Activatable>() == nullptr) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user