Skip to content

Commit

Permalink
use PropertyImplBase for Array, Set, and Struct property
Browse files Browse the repository at this point in the history
  • Loading branch information
moritz-h committed Feb 25, 2024
1 parent e8df71d commit 6726706
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 94 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
#pragma once

#include "../Arrays/Base/Array.h"
#include "Base/Property.h"
#include "Base/PropertyImpl.h"

namespace SatisfactorySave {

class SATISFACTORYSAVE_API ArrayProperty : public Property {
class SATISFACTORYSAVE_API ArrayProperty : public PropertyImplBase<ArrayProperty, std::unique_ptr<Array>> {
public:
static constexpr std::string_view TypeName = "ArrayProperty";

using Property::Property;
using PropertyImplBase<ArrayProperty, std::unique_ptr<Array>>::PropertyImplBase;

void serialize(Archive& ar) override;

void accept(PropertyVisitor& v) override;

[[nodiscard]] inline FName& arrayType() {
return tag_.InnerType;
}

[[nodiscard]] const std::unique_ptr<Array>& array() const {
return array_;
}

protected:
std::unique_ptr<Array> array_;
};
} // namespace SatisfactorySave
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,27 @@
namespace SatisfactorySave {

template<typename Impl, typename T>
class PropertyImpl : public Property {
class PropertyImplBase : public Property {
public:
PropertyImpl() : Property(FName(std::string(Impl::TypeName))) {}
explicit PropertyImpl(PropertyTag tag) : Property(std::move(tag)) {}

void serialize(Archive& ar) override {
if constexpr (IsSerializable<T>) {
ar << Value;
} else {
// Function must be overwritten by derived class!
// Runtime exception is a workaround for virtual functions not supporting concepts.
throw std::runtime_error("Invalid PropertyImpl serialize!");
}
}
PropertyImplBase() : Property(FName(std::string(Impl::TypeName))) {}
explicit PropertyImplBase(PropertyTag tag) : Property(std::move(tag)) {}

void accept(PropertyVisitor& v) override {
v.visit(static_cast<Impl&>(*this));
}

T Value{};
};

// Split into two classes to force subclasses with not serializable type to implement serialize(). Maybe in future
// override methods support concepts, e.g., `void serialize(Archive& ar) requires IsSerializable<T> override`.
template<typename Impl, typename T>
class PropertyImpl : public PropertyImplBase<Impl, T> {
public:
using PropertyImplBase<Impl, T>::PropertyImplBase;

void serialize(Archive& ar) override {
ar << this->Value;
}
};
} // namespace SatisfactorySave
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
#pragma once

#include "../Sets/Base/Set.h"
#include "Base/Property.h"
#include "Base/PropertyImpl.h"

namespace SatisfactorySave {

class SATISFACTORYSAVE_API SetProperty : public Property {
class SATISFACTORYSAVE_API SetProperty : public PropertyImplBase<SetProperty, std::unique_ptr<Set>> {
public:
static constexpr std::string_view TypeName = "SetProperty";

SetProperty(PropertyTag tag);
using PropertyImplBase<SetProperty, std::unique_ptr<Set>>::PropertyImplBase;

void serialize(Archive& ar) override;

void accept(PropertyVisitor& v) override;

[[nodiscard]] inline FName& setType() {
return tag_.InnerType;
}

[[nodiscard]] const std::unique_ptr<Set>& set() const {
return set_;
}

protected:
std::unique_ptr<Set> set_;
};
} // namespace SatisfactorySave
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,24 @@

#include "../Structs/Base/Struct.h"
#include "../UE/Misc/Guid.h"
#include "Base/Property.h"
#include "Base/PropertyImpl.h"

namespace SatisfactorySave {

class SATISFACTORYSAVE_API StructProperty : public Property {
class SATISFACTORYSAVE_API StructProperty : public PropertyImplBase<StructProperty, std::unique_ptr<Struct>> {
public:
static constexpr std::string_view TypeName = "StructProperty";

using Property::Property;
using PropertyImplBase<StructProperty, std::unique_ptr<Struct>>::PropertyImplBase;

void serialize(Archive& ar) override;

void accept(PropertyVisitor& v) override;

[[nodiscard]] inline FName& structName() {
return tag_.StructName;
}

[[nodiscard]] inline FGuid& structGuid() {
return tag_.StructGuid;
}

[[nodiscard]] const std::unique_ptr<Struct>& value() const {
return struct_;
}

protected:
std::unique_ptr<Struct> struct_;
};
} // namespace SatisfactorySave
10 changes: 2 additions & 8 deletions libsave/src/GameTypes/Properties/ArrayProperty.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
#include "GameTypes/Properties/ArrayProperty.h"

#include "GameTypes/Properties/Base/PropertyVisitor.h"

void SatisfactorySave::ArrayProperty::serialize(SatisfactorySave::Archive& ar) {
if (ar.isIArchive()) {
array_ = Array::create(arrayType(), ar);
Value = Array::create(arrayType(), ar);
} else {
ar << *array_;
ar << *Value;
}
}

void SatisfactorySave::ArrayProperty::accept(SatisfactorySave::PropertyVisitor& v) {
v.visit(*this);
}
14 changes: 2 additions & 12 deletions libsave/src/GameTypes/Properties/SetProperty.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
#include "GameTypes/Properties/SetProperty.h"

#include <utility>

#include "GameTypes/Properties/Base/PropertyVisitor.h"

SatisfactorySave::SetProperty::SetProperty(SatisfactorySave::PropertyTag tag) : Property(std::move(tag)) {}

void SatisfactorySave::SetProperty::serialize(Archive& ar) {
// https://github.com/EpicGames/UnrealEngine/blob/4.26.2-release/Engine/Source/Runtime/CoreUObject/Private/UObject/PropertySet.cpp#L298
int32_t NumElementsToRemove = 0;
Expand All @@ -16,12 +10,8 @@ void SatisfactorySave::SetProperty::serialize(Archive& ar) {

if (ar.isIArchive()) {
auto& inAr = dynamic_cast<IStreamArchive&>(ar);
set_ = Set::create(setType(), name(), inAr);
Value = Set::create(setType(), name(), inAr);
} else {
ar << *set_;
ar << *Value;
}
}

void SatisfactorySave::SetProperty::accept(SatisfactorySave::PropertyVisitor& v) {
v.visit(*this);
}
10 changes: 2 additions & 8 deletions libsave/src/GameTypes/Properties/StructProperty.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
#include "GameTypes/Properties/StructProperty.h"

#include "GameTypes/Properties/Base/PropertyVisitor.h"

void SatisfactorySave::StructProperty::serialize(Archive& ar) {
if (ar.isIArchive()) {
struct_ = Struct::create(structName(), ar);
Value = Struct::create(structName(), ar);
} else {
ar << *struct_;
ar << *Value;
}
}

void SatisfactorySave::StructProperty::accept(SatisfactorySave::PropertyVisitor& v) {
v.visit(*this);
}
6 changes: 3 additions & 3 deletions libsavepy/GameTypes/Properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void init_GameTypes_Properties(py::module_& m) {
;

py::class_<s::ArrayProperty, s::Property>(m, "ArrayProperty")
.def(py::init<s::PropertyTag>())
.def(py::init<>())
//.def_readwrite("Value", &s::ArrayProperty::Value) // TODO
;

Expand Down Expand Up @@ -125,7 +125,7 @@ void init_GameTypes_Properties(py::module_& m) {
.def_readwrite("Value", &s::ObjectProperty::Value);

py::class_<s::SetProperty, s::Property>(m, "SetProperty")
//.def(py::init<s::PropertyTag>()) // TODO
.def(py::init<>())
// TODO
;

Expand All @@ -138,7 +138,7 @@ void init_GameTypes_Properties(py::module_& m) {
.def_readwrite("Value", &s::StrProperty::Value);

py::class_<s::StructProperty, s::Property>(m, "StructProperty")
.def(py::init<s::PropertyTag>())
.def(py::init<>())
// TODO
;

Expand Down
14 changes: 7 additions & 7 deletions map/src/MapWindow/DataView/ModelManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ std::size_t Satisfactory3DMap::ModelManager::loadAsset(const std::string& classN
asset << instanceDataProperties;

const auto* instances = dynamic_cast<SatisfactorySave::StructArray*>(
instanceDataProperties.get<SatisfactorySave::ArrayProperty>("Instances").array().get());
instanceDataProperties.get<SatisfactorySave::ArrayProperty>("Instances").Value.get());
if (instances == nullptr || instances->Values.empty()) {
throw std::runtime_error("Instances not found or empty!");
}
Expand Down Expand Up @@ -233,7 +233,7 @@ std::size_t Satisfactory3DMap::ModelManager::loadAsset(const std::string& classN

glm::mat4 translationMx(1.0f);
try {
const auto& locationStructProp = properties.get<SatisfactorySave::StructProperty>("RelativeLocation").value();
const auto& locationStructProp = properties.get<SatisfactorySave::StructProperty>("RelativeLocation").Value;
const auto* locationStruct = dynamic_cast<const SatisfactorySave::VectorStruct*>(locationStructProp.get());
if (locationStruct != nullptr) {
translationMx = glm::translate(glm::mat4(1.0f), glmCast(locationStruct->Data));
Expand All @@ -242,7 +242,7 @@ std::size_t Satisfactory3DMap::ModelManager::loadAsset(const std::string& classN

glm::mat4 rotationMx(1.0f);
try {
const auto& rotationStructProp = properties.get<SatisfactorySave::StructProperty>("RelativeRotation").value();
const auto& rotationStructProp = properties.get<SatisfactorySave::StructProperty>("RelativeRotation").Value;
const auto* rotationStruct = dynamic_cast<const SatisfactorySave::RotatorStruct*>(rotationStructProp.get());
if (rotationStruct != nullptr) {
rotationMx = glm::toMat4(glmCast(rotationStruct->Data.Quaternion()));
Expand Down Expand Up @@ -288,17 +288,17 @@ Satisfactory3DMap::ModelManager::MeshInfo Satisfactory3DMap::ModelManager::getSt
try {
const auto& relativeTransform = instanceData->Data.get<SatisfactorySave::StructProperty>("RelativeTransform");
const auto* relativeTransformStruct =
dynamic_cast<SatisfactorySave::PropertyStruct*>(relativeTransform.value().get());
dynamic_cast<SatisfactorySave::PropertyStruct*>(relativeTransform.Value.get());
if (relativeTransformStruct == nullptr) {
throw std::runtime_error("Bad struct type!");
}

const auto* Rotation = dynamic_cast<const SatisfactorySave::QuatStruct*>(
relativeTransformStruct->Data.get<SatisfactorySave::StructProperty>("Rotation").value().get());
relativeTransformStruct->Data.get<SatisfactorySave::StructProperty>("Rotation").Value.get());
const auto* Translation = dynamic_cast<const SatisfactorySave::VectorStruct*>(
relativeTransformStruct->Data.get<SatisfactorySave::StructProperty>("Translation").value().get());
relativeTransformStruct->Data.get<SatisfactorySave::StructProperty>("Translation").Value.get());
const auto* Scale3D = dynamic_cast<const SatisfactorySave::VectorStruct*>(
relativeTransformStruct->Data.get<SatisfactorySave::StructProperty>("Scale3D").value().get());
relativeTransformStruct->Data.get<SatisfactorySave::StructProperty>("Scale3D").Value.get());
if (Rotation == nullptr || Translation == nullptr || Scale3D == nullptr) {
throw std::runtime_error("Bad struct types!");
}
Expand Down
8 changes: 4 additions & 4 deletions map/src/MapWindow/DataView/SplineData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace {
throw std::runtime_error("Expect StructProperty!");
}

auto& sa = dynamic_cast<SatisfactorySave::StructArray&>(*ap.array());
auto& sa = dynamic_cast<SatisfactorySave::StructArray&>(*ap.Value);
if (sa.structName() != "SplinePointData") {
throw std::runtime_error("Expect SplinePointData!");
}
Expand All @@ -32,11 +32,11 @@ namespace {
if (ps.Data.size() != 3) {
throw std::runtime_error("Unexpected struct size!");
}
const auto& locationStruct = *dynamic_cast<const SatisfactorySave::StructProperty&>(ps.Data.at(0)).value();
const auto& locationStruct = *dynamic_cast<const SatisfactorySave::StructProperty&>(ps.Data.at(0)).Value;
const auto& arriveTangentStruct =
*dynamic_cast<const SatisfactorySave::StructProperty&>(ps.Data.at(1)).value();
*dynamic_cast<const SatisfactorySave::StructProperty&>(ps.Data.at(1)).Value;
const auto& leaveTangentStruct =
*dynamic_cast<const SatisfactorySave::StructProperty&>(ps.Data.at(2)).value();
*dynamic_cast<const SatisfactorySave::StructProperty&>(ps.Data.at(2)).Value;

SplinePointData data;
data.location =
Expand Down
6 changes: 3 additions & 3 deletions map/src/MapWindow/UI/PropertyTableGuiRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ namespace {
void visit(SatisfactorySave::ArrayProperty& p) override {
ImGui::TextDisabled("ArrayType: %s", p.arrayType().toString().c_str());
ArraySetValueGuiRenderer r(callback_);
p.array()->accept(r);
p.Value->accept(r);
}

void visit(SatisfactorySave::BoolProperty& p) override {
Expand Down Expand Up @@ -461,7 +461,7 @@ namespace {
void visit(SatisfactorySave::SetProperty& p) override {
ImGui::TextDisabled("SetType: %s", p.setType().toString().c_str());
ArraySetValueGuiRenderer r(callback_);
p.set()->accept(r);
p.Value->accept(r);
}

void visit(SatisfactorySave::SoftObjectProperty& p) override {
Expand All @@ -479,7 +479,7 @@ namespace {
ImGui::Text("%s", p.structName().toString().c_str());
ImGui::TextDisabled("%s", p.structGuid().toString().c_str());
StructValueGuiRenderer s(callback_);
p.value()->accept(s);
p.Value->accept(s);
}

void visit(SatisfactorySave::TextProperty& p) override {
Expand Down

0 comments on commit 6726706

Please sign in to comment.