From ff6fc8f9832e54929e7cc1305ab159d4f52e5ad6 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Apr 2024 22:46:13 -0400 Subject: [PATCH 01/17] XMLSerializer with visitor WIP --- xLights/models/ArchesModel.h | 4 +- xLights/models/BaseObjectVisitor.h | 44 +- xLights/models/CandyCaneModel.cpp | 2 + xLights/models/CandyCaneModel.h | 5 + xLights/models/CircleModel.h | 3 + xLights/models/ModelGroup.cpp | 4 +- xLights/models/ModelGroup.h | 4 +- xLights/models/ModelManager.cpp | 15 +- xLights/models/ModelManager.h | 3 +- xLights/models/XmlSerializer.h | 773 ++++++++++++++++++++++------- 10 files changed, 657 insertions(+), 200 deletions(-) diff --git a/xLights/models/ArchesModel.h b/xLights/models/ArchesModel.h index 5180c7b0c5..c0d07c70fc 100644 --- a/xLights/models/ArchesModel.h +++ b/xLights/models/ArchesModel.h @@ -42,8 +42,8 @@ class ArchesModel : public ModelWithScreenLocation int GetHollow() const { return _hollow; } int GetGap() const { return _gap; } - //virtual bool SupportsVisitors() override {return true;} - //void Accept(BaseObjectVisitor &visitor) const override { return visitor.Visit(*this); } + virtual bool SupportsVisitors() override {return true;} + void Accept(BaseObjectVisitor &visitor) const override { return visitor.Visit(*this); } protected: virtual void InitModel() override; diff --git a/xLights/models/BaseObjectVisitor.h b/xLights/models/BaseObjectVisitor.h index 20eabb10e0..c34fe61e23 100644 --- a/xLights/models/BaseObjectVisitor.h +++ b/xLights/models/BaseObjectVisitor.h @@ -11,12 +11,44 @@ **************************************************************/ class ArchesModel; +class CandyCaneModel; +class ChannelBlockModel; +class CircleModel; +class CubeModel; +class CustomModel; +class ImageModel; +class IciclesModel; +class MatrixModel; +class SingleLineModel; +class PolyLineModel; +class SphereModel; +class SpinnerModel; +class StarModel; +class TreeModel; +class WindowFrameModel; +class WreathModel; class DmxMovingHeadAdv; -struct BaseObjectVisitor -{ - virtual void Visit(const ArchesModel &arch) = 0; - virtual void Visit(const DmxMovingHeadAdv &moving_head) = 0; +struct BaseObjectVisitor { + virtual void Visit(const ArchesModel& arch) = 0; + virtual void Visit(const CandyCaneModel& cc) = 0; + virtual void Visit(const ChannelBlockModel& channelblock) = 0; + virtual void Visit(const CircleModel& circle) = 0; + virtual void Visit(const CubeModel& cube) = 0; + virtual void Visit(const CustomModel& custom) = 0; + virtual void Visit(const ImageModel& image) = 0; + virtual void Visit(const IciclesModel& icicles) = 0; + virtual void Visit(const MatrixModel& matrix) = 0; + virtual void Visit(const SingleLineModel& singleline) = 0; + virtual void Visit(const PolyLineModel& polyline) = 0; + virtual void Visit(const SphereModel& sphere) = 0; + virtual void Visit(const SpinnerModel& spinner) = 0; + virtual void Visit(const StarModel& start) = 0; + virtual void Visit(const TreeModel& tree) = 0; + virtual void Visit(const WindowFrameModel& window) = 0; + virtual void Visit(const WreathModel& wreath) = 0; + virtual void Visit(const DmxMovingHeadAdv& moving_head) = 0; - virtual ~BaseObjectVisitor() {} -}; + virtual ~BaseObjectVisitor() { + } +}; \ No newline at end of file diff --git a/xLights/models/CandyCaneModel.cpp b/xLights/models/CandyCaneModel.cpp index e97c210ab5..94da3e612c 100644 --- a/xLights/models/CandyCaneModel.cpp +++ b/xLights/models/CandyCaneModel.cpp @@ -364,6 +364,8 @@ static void rotate_point(float cx,float cy, float angle, float &x, float &y) y = ynew + cy; } +void CandyCaneModel::ExportXlightsModel() {} + void CandyCaneModel::SetCaneCoord() { static log4cpp::Category& logger_base = log4cpp::Category::getInstance(std::string("log_base")); diff --git a/xLights/models/CandyCaneModel.h b/xLights/models/CandyCaneModel.h index 569d65fef8..5078e07618 100644 --- a/xLights/models/CandyCaneModel.h +++ b/xLights/models/CandyCaneModel.h @@ -27,11 +27,16 @@ class CandyCaneModel : public ModelWithScreenLocation virtual void AddTypeProperties(wxPropertyGridInterface* grid, OutputManager* outputManager) override; virtual void UpdateTypeProperties(wxPropertyGridInterface* grid) override; virtual int OnPropertyGridChange(wxPropertyGridInterface *grid, wxPropertyGridEvent& event) override; + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; virtual bool SupportsExportAsCustom() const override { return true; } virtual bool SupportsWiringView() const override { return true; } virtual std::string GetDimension() const override; virtual void AddDimensionProperties(wxPropertyGridInterface* grid) override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: virtual void InitModel() override; virtual int MapToNodeIndex(int strand, int node) const override; diff --git a/xLights/models/CircleModel.h b/xLights/models/CircleModel.h index a5417d2439..d9a5620a5d 100644 --- a/xLights/models/CircleModel.h +++ b/xLights/models/CircleModel.h @@ -35,6 +35,9 @@ class CircleModel : public ModelWithScreenLocation virtual bool ModelSupportsLayerSizes() const override { return true; } virtual void OnLayerSizesChange(bool countChanged) override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: virtual void InitModel() override; diff --git a/xLights/models/ModelGroup.cpp b/xLights/models/ModelGroup.cpp index 46014756cb..d72f4ab27f 100644 --- a/xLights/models/ModelGroup.cpp +++ b/xLights/models/ModelGroup.cpp @@ -194,7 +194,7 @@ bool ModelGroup::ContainsModelOrSubmodel(Model* m) const return found; } -bool ModelGroup::ContainsModel(Model* m) const +bool ModelGroup::ContainsModel(const Model* m) const { wxASSERT(m->GetDisplayAs() != "ModelGroup"); @@ -227,7 +227,7 @@ bool ModelGroup::ContainsModel(Model* m) const return found; } -bool ModelGroup::ContainsModel(Model* m, std::list& visited) const +bool ModelGroup::ContainsModel(const Model* m, std::list& visited) const { visited.push_back(this); diff --git a/xLights/models/ModelGroup.h b/xLights/models/ModelGroup.h index fd8984bfb1..173a14da20 100644 --- a/xLights/models/ModelGroup.h +++ b/xLights/models/ModelGroup.h @@ -54,8 +54,8 @@ class ModelGroup : public ModelWithScreenLocation bool ContainsModelGroup(ModelGroup* mg, std::set& visited); bool DirectlyContainsModel(Model* m) const; bool DirectlyContainsModel(std::string const& m) const; - bool ContainsModel(Model* m) const; - bool ContainsModel(Model* m, std::list& visited) const; + bool ContainsModel(const Model* m) const; + bool ContainsModel(const Model* m, std::list& visited) const; bool ContainsModelOrSubmodel(Model* m) const; bool ContainsModelOrSubmodel(Model* m, std::list& visited) const; bool OnlyContainsModel(const std::string& name) const; diff --git a/xLights/models/ModelManager.cpp b/xLights/models/ModelManager.cpp index 4df8d00093..c89678bffa 100644 --- a/xLights/models/ModelManager.cpp +++ b/xLights/models/ModelManager.cpp @@ -1700,7 +1700,7 @@ std::string ModelManager::GetModelsOnChannels(uint32_t start, uint32_t end, int return res; } -std::vector ModelManager::GetGroupsContainingModel(Model* model) const +std::vector ModelManager::GetGroupsContainingModel(const Model* model) const { std::vector res; for (const auto& it : *this) { @@ -1742,6 +1742,19 @@ std::vector ModelManager::GetGroupsContainingModelOrSubmodel(Model* return res; } +std::vector ModelManager::GetModelGroups(const Model* model) const { + std::vector res; + for (const auto& it : *this) { + if (it.second->GetDisplayAs() == "ModelGroup") { + auto mg = dynamic_cast(it.second); + if (mg->ContainsModel(model)) { + res.push_back(mg); + } + } + } + return res; +} + std::string ModelManager::GenerateNewStartChannel(const std::string& lastModel) const { std::string startChannel = "1"; diff --git a/xLights/models/ModelManager.h b/xLights/models/ModelManager.h index dd286970b0..a45c440d68 100644 --- a/xLights/models/ModelManager.h +++ b/xLights/models/ModelManager.h @@ -82,8 +82,9 @@ class ModelManager : public ObjectManager bool IsValidControllerModelChain(Model* m, std::string& tip) const; Model *createAndAddModel(wxXmlNode *node, int previewW, int previewH); std::string GetModelsOnChannels(uint32_t start, uint32_t end, int perLine) const; - std::vector GetGroupsContainingModel(Model* model) const; + std::vector GetGroupsContainingModel(const Model* model) const; std::vector GetGroupsContainingModelOrSubmodel(Model* model) const; + std::vector GetModelGroups(const Model* model) const; std::string GenerateNewStartChannel(const std::string& lastModel = "") const; int GetPreviewWidth() const { return previewWidth; } diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 38c28649c5..a8ecbe228c 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -15,141 +15,379 @@ #include "ArchesModel.h" #include "BaseObject.h" #include "BaseObjectVisitor.h" +#include "CandyCaneModel.h" +#include "ChannelBlockModel.h" +#include "CircleModel.h" +#include "CubeModel.h" +#include "CustomModel.h" +#include "IciclesModel.h" +#include "ImageModel.h" +#include "MatrixModel.h" +#include "PolyLineModel.h" +#include "SingleLineModel.h" +#include "SphereModel.h" +#include "SpinnerModel.h" +#include "StarModel.h" +#include "ThreePointScreenLocation.h" +#include "TreeModel.h" +#include "WindowFrameModel.h" +#include "WreathModel.h" #include "DMX/DmxColorAbilityCMY.h" #include "DMX/DmxColorAbilityRGB.h" #include "DMX/DmxColorAbilityWheel.h" #include "DMX/DmxMovingHeadAdv.h" #include "DMX/Mesh.h" -#include "ThreePointScreenLocation.h" - -namespace XmlNodeKeys -{ -// Model Node Names -constexpr auto ModelsNodeName = "models"; -constexpr auto ModelNodeName = "model"; -constexpr auto TypeAttribute = "type"; -constexpr auto ExportedAttribute = "exported"; - -// Common BaseObject Attributes -constexpr auto NameAttribute = "name"; -constexpr auto DisplayAsAttribute = "DisplayAs"; -constexpr auto LayoutGroupAttribute = "LayoutGroup"; - -// Common Model Attributes -constexpr auto StartSideAttribute = "StartSide"; -constexpr auto DirAttribute = "Dir"; -constexpr auto Parm1Attribute = "parm1"; -constexpr auto Parm2Attribute = "parm2"; -constexpr auto Parm3Attribute = "parm3"; -constexpr auto AntialiasAttribute = "Antialias"; -constexpr auto PixelSizeAttribute = "PixelSize"; -constexpr auto StringTypeAttribute = "StringType"; -constexpr auto TransparencyAttribute = "Transparency"; -constexpr auto StartChannelAttribute = "StartChannel"; -constexpr auto NodeNamesAttribute = "NodeNames"; -constexpr auto StrandNamesAttribute = "StrandNames"; -constexpr auto ControllerAttribute = "Controller"; -constexpr auto versionNumberAttribute = "versionNumber"; - -// Size/Position Attributes -constexpr auto WorldPosXAttribute = "WorldPosX"; -constexpr auto WorldPosYAttribute = "WorldPosY"; -constexpr auto WorldPosZAttribute = "WorldPosZ"; -constexpr auto ScaleXAttribute = "ScaleX"; -constexpr auto ScaleYAttribute = "ScaleY"; -constexpr auto ScaleZAttribute = "ScaleZ"; -constexpr auto RotateXAttribute = "RotateX"; -constexpr auto RotateYAttribute = "RotateY"; -constexpr auto RotateZAttribute = "RotateZ"; -constexpr auto WidthAttribute = "Width"; -constexpr auto HeightAttribute = "Height"; -constexpr auto DepthAttribute = "Depth"; -constexpr auto OffsetXAttribute = "OffsetX"; -constexpr auto OffsetYAttribute = "OffsetY"; -constexpr auto OffsetZAttribute = "OffsetZ"; - -// Model Screen Location Attributes -constexpr auto LockedAttribute = "Locked"; - -// TwoPoint Screen Location Attributes -constexpr auto X2Attribute = "X2"; -constexpr auto Y2Attribute = "Y2"; -constexpr auto Z2Attribute = "Z2"; - -// ThreePoint Screen Location Attributes -constexpr auto AngleAttribute = "Angle"; -constexpr auto ShearAttribute = "Shear"; - -// DmxColorAbilityRGB Attributes -constexpr auto DmxRedChannelAttribute = "DmxRedChannel"; -constexpr auto DmxGreenChannelAttribute = "DmxGreenChannel"; -constexpr auto DmxBlueChannelAttribute = "DmxBlueChannel"; -constexpr auto DmxWhiteChannelAttribute = "DmxWhiteChannel"; - -// DmxColorAbilityWheel Attributes -constexpr auto DmxColorWheelChannelAttribute = "DmxColorWheelChannel"; -constexpr auto DmxDimmerChannelAttribute = "DmxDimmerChannel"; -constexpr auto DmxColorWheelColorAttribute = "DmxColorWheelColor"; -constexpr auto DmxColorWheelDMXAttribute = "DmxColorWheelDMX"; - -// DmxColorAbilityCMY Attributes -constexpr auto DmxCyanChannelAttribute = "DmxCyanChannel"; -constexpr auto DmxMagentaChannelAttribute = "DmxMagentaChannel"; -constexpr auto DmxYellowChannelAttribute = "DmxYellowChannel"; - -// DmxMovingHeadComm Attributes -constexpr auto DmxFixturelAttribute = "DmxFixture"; - -// DMX Moving Head Attributes -constexpr auto DmxColorTypeAttribute = "DmxColorType"; -constexpr auto DmxBeamYOffsetAttribute = "DmxBeamYOffset"; -constexpr auto DmxBeamLengthAttribute = "DmxBeamLength"; - -// DmxMotor Attributes -constexpr auto ChannelCoarseAttribute = "ChannelCoarse"; -constexpr auto ChannelFineAttribute = "ChannelFine"; -constexpr auto MinLimitAttribute = "MinLimit"; -constexpr auto MaxLimitAttribute = "MaxLimit"; -constexpr auto RangeOfMotionAttribute = "RangeOfMotion"; -constexpr auto OrientZeroAttribute = "OrientZero"; -constexpr auto OrientHomeAttribute = "OrientHome"; -constexpr auto SlewLimitAttribute = "SlewLimit"; -constexpr auto ReverseAttribute = "Reverse"; -constexpr auto UpsideDownAttribute = "UpsideDown"; - -// Arch Attributes -constexpr auto ZigZagAttribute = "ZigZag"; -constexpr auto HollowAttribute = "Hollow"; -constexpr auto GapAttribute = "Gap"; - -// Mesh Attributes -constexpr auto ObjFileAttribute = "ObjFile"; -constexpr auto MeshOnlyAttribute = "MeshOnly"; -constexpr auto BrightnessAttribute = "Brightness"; - -// Model Types -constexpr auto ArchesType = "Arches"; -constexpr auto DmxMovingHeadAdvType = "DmxMovingHeadAdv"; +namespace XmlNodeKeys { + // Model Node Names + constexpr auto ModelsNodeName = "models"; + constexpr auto ModelNodeName = "model"; + constexpr auto TypeAttribute = "type"; + constexpr auto ExportedAttribute = "exported"; + + // Common BaseObject Attributes + constexpr auto NameAttribute = "name"; + constexpr auto DisplayAsAttribute = "DisplayAs"; + constexpr auto LayoutGroupAttribute = "LayoutGroup"; + + // Common Model Attributes + constexpr auto StartSideAttribute = "StartSide"; + constexpr auto DirAttribute = "Dir"; + constexpr auto Parm1Attribute = "parm1"; + constexpr auto Parm2Attribute = "parm2"; + constexpr auto Parm3Attribute = "parm3"; + constexpr auto AntialiasAttribute = "Antialias"; + constexpr auto PixelSizeAttribute = "PixelSize"; + constexpr auto StringTypeAttribute = "StringType"; + constexpr auto TransparencyAttribute = "Transparency"; + constexpr auto BTransparencyAttribute = "BlackTransparency"; + constexpr auto StartChannelAttribute = "StartChannel"; + constexpr auto NodeNamesAttribute = "NodeNames"; + constexpr auto StrandNamesAttribute = "StrandNames"; + constexpr auto ControllerAttribute = "Controller"; + constexpr auto versionNumberAttribute = "versionNumber"; + constexpr auto ActiveAttribute = "Active"; + constexpr auto FromBaaseAttribute = "FromBase"; + constexpr auto DescriptionAttribute = "Description"; + + // Common SubModel Attributes + constexpr auto SubModelNodeName = "subModel"; + constexpr auto SubModelNameAttribute = "name"; + constexpr auto LayoutAttribute = "layout"; + constexpr auto SMTypeAttribute = "type"; + constexpr auto BufferStyleAttribute = "bufferstyle"; + constexpr auto SubBufferStyleAttribute = "subBuffer"; + constexpr auto Line0Attribute = "line0"; + + //AddAttribute(XmlNodeKeys::NameAttribute, base.GetName()); node->AddAttribute(XmlNodeKeys::DisplayAsAttribute, base.GetDisplayAs()); node->AddAttribute(XmlNodeKeys::LayoutGroupAttribute, base.GetLayoutGroup()); } - void AddCommonModelAttributes(const Model &model, wxXmlNode *node) - { + void AddCommonModelAttributes(const Model& model, wxXmlNode* node) { node->AddAttribute(XmlNodeKeys::StartSideAttribute, model.GetStartSide()); node->AddAttribute(XmlNodeKeys::DirAttribute, model.GetDirection()); node->AddAttribute(XmlNodeKeys::Parm1Attribute, std::to_string(model.GetParm1())); @@ -166,8 +404,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor node->AddAttribute(XmlNodeKeys::versionNumberAttribute, CUR_MODEL_POS_VER); } - void AddModelScreenLocationAttributes(const BaseObject &base, wxXmlNode *node) - { + void AddModelScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { glm::vec3 loc = base.GetBaseObjectScreenLocation().GetWorldPosition(); node->AddAttribute(XmlNodeKeys::WorldPosXAttribute, std::to_string(loc.x)); node->AddAttribute(XmlNodeKeys::WorldPosYAttribute, std::to_string(loc.y)); @@ -184,8 +421,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor node->AddAttribute(XmlNodeKeys::LockedAttribute, std::to_string(locked)); } - void AddThreePointScreenLocationAttributes(const BaseObject &base, wxXmlNode *node) - { + void AddThreePointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { const ThreePointScreenLocation& screenLoc = dynamic_cast(base.GetBaseObjectScreenLocation()); float x2 = screenLoc.GetX2(); float y2 = screenLoc.GetY2(); @@ -200,53 +436,49 @@ struct XmlSerializingVisitor : BaseObjectVisitor node->AddAttribute(XmlNodeKeys::HeightAttribute, std::to_string(base.GetHeight())); } - void AddColorAbilityRGBAttributes(const DmxColorAbilityRGB *colors, wxXmlNode *node) - { + void AddColorAbilityRGBAttributes(const DmxColorAbilityRGB* colors, wxXmlNode* node) { node->AddAttribute(XmlNodeKeys::DmxRedChannelAttribute, std::to_string(colors->GetRedChannel())); node->AddAttribute(XmlNodeKeys::DmxGreenChannelAttribute, std::to_string(colors->GetGreenChannel())); node->AddAttribute(XmlNodeKeys::DmxBlueChannelAttribute, std::to_string(colors->GetBlueChannel())); node->AddAttribute(XmlNodeKeys::DmxWhiteChannelAttribute, std::to_string(colors->GetWhiteChannel())); } - void AddColorWheelAttributes(const DmxColorAbilityWheel *colors, wxXmlNode *node) - { + void AddColorWheelAttributes(const DmxColorAbilityWheel* colors, wxXmlNode* node) { node->AddAttribute(XmlNodeKeys::DmxColorWheelChannelAttribute, std::to_string(colors->GetWheelChannel())); node->AddAttribute(XmlNodeKeys::DmxDimmerChannelAttribute, std::to_string(colors->GetDimmerChannel())); std::vector settings = colors->GetWheelColorSettings(); int index = 0; - for (const auto& it : settings) - { + for (const auto& it : settings) { node->AddAttribute(XmlNodeKeys::DmxColorWheelColorAttribute + std::to_string(index), (std::string)it.color); node->AddAttribute(XmlNodeKeys::DmxColorWheelDMXAttribute + std::to_string(index), std::to_string(it.dmxValue)); ++index; } } - void AddColorAbilityCMYAttributes(const DmxColorAbilityCMY *colors, wxXmlNode *node) - { + void AddColorAbilityCMYAttributes(const DmxColorAbilityCMY* colors, wxXmlNode* node) { node->AddAttribute(XmlNodeKeys::DmxCyanChannelAttribute, std::to_string(colors->GetCyanChannel())); node->AddAttribute(XmlNodeKeys::DmxMagentaChannelAttribute, std::to_string(colors->GetMagentaChannel())); node->AddAttribute(XmlNodeKeys::DmxYellowChannelAttribute, std::to_string(colors->GetYellowChannel())); node->AddAttribute(XmlNodeKeys::DmxWhiteChannelAttribute, std::to_string(colors->GetWhiteChannel())); } - void AddColorAttributes(const DmxModel &dmx_model, wxXmlNode *node) { + void AddColorAttributes(const DmxModel& dmx_model, wxXmlNode* node) { if (dmx_model.HasColorAbility()) { DmxColorAbility* color_ability = dmx_model.GetColorAbility(); std::string color_type = color_ability->GetTypeName(); node->AddAttribute(XmlNodeKeys::DmxColorTypeAttribute, std::to_string(dmx_model.DmxColorTypetoID(color_type))); - if (color_type == "RGBW" ) { - AddColorAbilityRGBAttributes( reinterpret_cast(color_ability), node); - } else if (color_type == "ColorWheel" ) { - AddColorWheelAttributes( reinterpret_cast(color_ability), node); - } else if (color_type == "CMYW" ) { - AddColorAbilityCMYAttributes( reinterpret_cast(color_ability), node); + if (color_type == "RGBW") { + AddColorAbilityRGBAttributes(reinterpret_cast(color_ability), node); + } else if (color_type == "ColorWheel") { + AddColorWheelAttributes(reinterpret_cast(color_ability), node); + } else if (color_type == "CMYW") { + AddColorAbilityCMYAttributes(reinterpret_cast(color_ability), node); } } } - void AddDmxMotorAttributes(const DmxMotor *motor, wxXmlNode *node) { - wxXmlNode *motor_node = new wxXmlNode(wxXML_ELEMENT_NODE, motor->GetName()); + void AddDmxMotorAttributes(const DmxMotor* motor, wxXmlNode* node) { + wxXmlNode* motor_node = new wxXmlNode(wxXML_ELEMENT_NODE, motor->GetName()); motor_node->AddAttribute(XmlNodeKeys::ChannelCoarseAttribute, std::to_string(motor->GetChannelCoarse())); motor_node->AddAttribute(XmlNodeKeys::ChannelFineAttribute, std::to_string(motor->GetChannelFine())); motor_node->AddAttribute(XmlNodeKeys::MinLimitAttribute, std::to_string(motor->GetMinLimit())); @@ -260,8 +492,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor node->AddChild(motor_node); } - void AddMeshAttributes(const Mesh *mesh, wxXmlNode *node) { - wxXmlNode *mesh_node = new wxXmlNode(wxXML_ELEMENT_NODE, mesh->GetName()); + void AddMeshAttributes(const Mesh* mesh, wxXmlNode* node) { + wxXmlNode* mesh_node = new wxXmlNode(wxXML_ELEMENT_NODE, mesh->GetName()); mesh_node->AddAttribute(XmlNodeKeys::ObjFileAttribute, mesh->GetObjFile()); mesh_node->AddAttribute(XmlNodeKeys::MeshOnlyAttribute, std::to_string(mesh->GetMeshOnly())); mesh_node->AddAttribute(XmlNodeKeys::BrightnessAttribute, std::to_string(mesh->GetBrightness())); @@ -280,9 +512,82 @@ struct XmlSerializingVisitor : BaseObjectVisitor node->AddChild(mesh_node); } - void Visit(const ArchesModel &arch) override - { - wxXmlNode *archNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + wxString vectorToString(const std::vector& v, const std::string& separator = ",") { + wxString oss; + for (size_t i = 0; i < v.size(); ++i) { + oss << v[i]; + if (i < v.size() - 1) { + oss << separator; + } + } + return oss; + } + + void AddSubmodels(wxXmlNode* node, Model* sm) { + wxXmlNode* submodels = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::SubModelNodeName); + submodels->AddAttribute(XmlNodeKeys::SubModelNameAttribute, sm->GetName()); + const std::list& aliases = sm->GetAliases(); + + // const Model* m = dynamic_cast(sm); + // const ModelManager& mgr = m->GetModelManager(); + + submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, "foo"); + submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, "bar"); + submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, "baz"); + submodels->AddAttribute(XmlNodeKeys::SubBufferStyleAttribute, "foobarbaz"); + submodels->AddAttribute(XmlNodeKeys::Line0Attribute, "foobarbaz"); + AddAliases(submodels, aliases); + node->AddChild(submodels); + } + + void AddGroups(wxXmlNode* node, std::vector groups, const std::string name) { + for (const auto& g : groups) { + wxXmlNode* groups = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::GroupNodeName); + groups->AddAttribute(XmlNodeKeys::mgNameAttribute, g); + groups->AddAttribute(XmlNodeKeys::mgModelsAttribute, name); + groups->AddAttribute(XmlNodeKeys::mgLayoutGroupAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgSelectedAttribute, "foo"); + groups->AddAttribute(XmlNodeKeys::mgLayoutAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgGridSizeAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgTagColourAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentreMinxAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentreMinyAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentreMaxxAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentreMaxyAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentrexAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentreyAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgCentreDefinedAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgDefaultCameraAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgxCentreOffsetAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgyCentreOffsetAttribute, "foobarbaz"); + // AddAliases(groups,aliases); + node->AddChild(groups); + } + } + + void AddAliases(wxXmlNode* node, const std::list aliases) { + wxXmlNode* aliashdr = new wxXmlNode(wxXML_ELEMENT_NODE, "Aliases"); + + for (const auto& a : aliases) { + wxXmlNode* alias = new wxXmlNode(wxXML_ELEMENT_NODE, "alias"); + alias->AddAttribute("name", a); + aliashdr->AddChild(alias); + } + node->AddChild(aliashdr); + } + + void Visit(const ArchesModel& arch) override { + wxXmlNode* archNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + + const std::vector& submodels = arch.GetSubModels(); + const std::list& aliases = arch.GetAliases(); + const std::string name = arch.GetName(); + + const Model* m = dynamic_cast(&arch); + const ModelManager& mgr = m->GetModelManager(); + std::vector groups = mgr.GetGroupsContainingModel(m); + std::vector modelGroups = mgr.GetModelGroups(m); + AddBaseObjectAttributes(arch, archNode); AddCommonModelAttributes(arch, archNode); AddModelScreenLocationAttributes(arch, archNode); @@ -290,12 +595,97 @@ struct XmlSerializingVisitor : BaseObjectVisitor archNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, std::to_string(arch.GetZigZag())); archNode->AddAttribute(XmlNodeKeys::HollowAttribute, std::to_string(arch.GetHollow())); archNode->AddAttribute(XmlNodeKeys::GapAttribute, std::to_string(arch.GetGap())); + archNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(arch.GetLayerSizes())); + AddAliases(archNode, aliases); + for (Model* submodel : submodels) { + Model* sm = arch.GetSubModel(submodel->GetName()); + AddSubmodels(archNode, sm); + } + AddGroups(archNode, groups, name); parentNode->AddChild(archNode); } - void Visit(const DmxMovingHeadAdv &moving_head) override - { - wxXmlNode *mhNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + void Visit(const CandyCaneModel& cc) override { + wxXmlNode* ccNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + + const std::vector& submodels = cc.GetSubModels(); + const std::list& aliases = cc.GetAliases(); + const std::string name = cc.GetName(); + + const Model* m = dynamic_cast(&cc); + const ModelManager& mgr = m->GetModelManager(); + std::vector groups = mgr.GetGroupsContainingModel(m); + + AddBaseObjectAttributes(cc, ccNode); + AddCommonModelAttributes(cc, ccNode); + AddModelScreenLocationAttributes(cc, ccNode); + AddThreePointScreenLocationAttributes(cc, ccNode); + AddAliases(ccNode, aliases); + for (Model* submodel : submodels) { + Model* sm = cc.GetSubModel(submodel->GetName()); + AddSubmodels(ccNode, sm); + } + AddGroups(ccNode, groups, name); + parentNode->AddChild(ccNode); + } + + void Visit(const CircleModel& circle) override { + wxXmlNode* circleNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + + const std::vector& submodels = circle.GetSubModels(); + const std::list& aliases = circle.GetAliases(); + const std::string name = circle.GetName(); + + const Model* m = dynamic_cast(&circle); + const ModelManager& mgr = m->GetModelManager(); + std::vector groups = mgr.GetGroupsContainingModel(m); + + AddBaseObjectAttributes(circle, circleNode); + AddCommonModelAttributes(circle, circleNode); + AddModelScreenLocationAttributes(circle, circleNode); + // AddThreePointScreenLocationAttributes(circle, circleNode); //export crashes, most likely an attribute that doesn't exist - need to look into + AddAliases(circleNode, aliases); + for (Model* submodel : submodels) { + Model* sm = circle.GetSubModel(submodel->GetName()); + AddSubmodels(circleNode, sm); + } + AddGroups(circleNode, groups, name); + parentNode->AddChild(circleNode); + } + + void Visit(const ChannelBlockModel& channelblock) override { + } + void Visit(const CubeModel& cube) override { + } + void Visit(const CustomModel& custom) override { + } + void Visit(const IciclesModel& icicles) override { + } + void Visit(const ImageModel& image) override { + } + void Visit(const MatrixModel& matricx) override { + } + void Visit(const SingleLineModel& singleline) override { + } + void Visit(const PolyLineModel& polyline) override { + } + void Visit(const SphereModel& sphere) override { + } + void Visit(const SpinnerModel& spinner) override { + } + void Visit(const StarModel& star) override { + } + void Visit(const TreeModel& tree) override { + } + // void Visit(const TreeModel &treeflat) override {} + // void Visit(const TreeModel &treeribbon) override {} + void Visit(const WindowFrameModel& window) override { + } + void Visit(const WreathModel& wreath) override { + } + + void Visit(const DmxMovingHeadAdv& moving_head) override { + wxXmlNode* mhNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); AddBaseObjectAttributes(moving_head, mhNode); AddCommonModelAttributes(moving_head, mhNode); AddModelScreenLocationAttributes(moving_head, mhNode); @@ -312,18 +702,17 @@ struct XmlSerializingVisitor : BaseObjectVisitor } }; -struct XmlDeserializingObjectFactory -{ - Model* Deserialize(wxXmlNode *node, xLightsFrame* xlights) - { +struct XmlDeserializingObjectFactory { + Model* Deserialize(wxXmlNode* node, xLightsFrame* xlights) { auto type = node->GetAttribute(XmlNodeKeys::DisplayAsAttribute); - if (type == XmlNodeKeys::ArchesType) - { + if (type == XmlNodeKeys::ArchesType) { return DeserializeArches(new wxXmlNode(*node), xlights); - } - else if (type == XmlNodeKeys::DmxMovingHeadAdvType) - { + } else if (type == XmlNodeKeys::CandyCaneType) { + return DeserializeCandyCane(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::CircleType) { + return DeserializeCircle(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::DmxMovingHeadAdvType) { return DeserializeDmxMovingHeadAdv(new wxXmlNode(*node), xlights); } @@ -331,10 +720,8 @@ struct XmlDeserializingObjectFactory } private: - - Model* DeserializeArches(wxXmlNode *node, xLightsFrame* xlights) - { - Model *model; + Model* DeserializeArches(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; model = new ArchesModel(node, xlights->AllModels, false); std::string name = node->GetAttribute("name"); @@ -344,9 +731,30 @@ struct XmlDeserializingObjectFactory return model; } - Model* DeserializeDmxMovingHeadAdv(wxXmlNode *node, xLightsFrame* xlights) - { - Model *model; + Model* DeserializeCandyCane(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new CandyCaneModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeCircle(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new CircleModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeDmxMovingHeadAdv(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; model = new DmxMovingHeadAdv(node, xlights->AllModels, false); std::string name = node->GetAttribute("name"); @@ -364,15 +772,12 @@ struct XmlDeserializingObjectFactory } }; -struct XmlSerializer -{ - XmlSerializer() - { +struct XmlSerializer { + XmlSerializer() { } // Serializes and Saves a single model into an XML document - void SerializeAndSaveModel(const BaseObject &object) - { + void SerializeAndSaveModel(const BaseObject& object) { wxString name = object.GetModelXml()->GetAttribute("name"); wxString filename = wxFileSelector(_("Choose output file"), wxEmptyString, name, wxEmptyString, "Custom Model files (*.xmodel)|*.xmodel", wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (filename.IsEmpty()) @@ -382,33 +787,30 @@ struct XmlSerializer } // Serialize a single model into an XML document - wxXmlDocument SerializeModel(const BaseObject &object) - { + wxXmlDocument SerializeModel(const BaseObject& object) { wxXmlDocument doc; - - wxXmlNode *docNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelsNodeName); + + wxXmlNode* docNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelsNodeName); docNode->AddAttribute(XmlNodeKeys::TypeAttribute, XmlNodeKeys::ExportedAttribute); - XmlSerializingVisitor visitor{docNode}; - + XmlSerializingVisitor visitor{ docNode }; + object.Accept(visitor); - + doc.SetRoot(docNode); - + return doc; } // Deserialize a single model from an XML document - Model* DeserializeModel(const wxXmlDocument &doc, xLightsFrame* xlights) - { - wxXmlNode *root = doc.GetRoot(); - wxXmlNode *model_node = root->GetChildren(); + Model* DeserializeModel(const wxXmlDocument& doc, xLightsFrame* xlights) { + wxXmlNode* root = doc.GetRoot(); + wxXmlNode* model_node = root->GetChildren(); return DeserializeModel(model_node, xlights); } // Deserialize a single model XML node - Model* DeserializeModel(wxXmlNode *model_node, xLightsFrame* xlights) - { + Model* DeserializeModel(wxXmlNode* model_node, xLightsFrame* xlights) { XmlDeserializingObjectFactory factory{}; Model* model = factory.Deserialize(model_node, xlights); @@ -418,8 +820,7 @@ struct XmlSerializer float min_y = (float)(model->GetBaseObjectScreenLocation().GetBottom()); float max_y = (float)(model->GetBaseObjectScreenLocation().GetTop()); model->ImportModelChildren(model->GetModelXml(), xlights, model->GetName(), min_x, max_x, min_y, max_y); - + return model; } - }; From 6fcaa269758c6ba32dde78d0076794112ece2547 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 7 May 2024 23:56:23 -0400 Subject: [PATCH 02/17] XMLSerializer with visitor WIP --- xLights/models/ModelGroup.h | 11 ++++ xLights/models/SubModel.h | 7 +- xLights/models/XmlSerializer.h | 113 +++++++++++++++++---------------- 3 files changed, 76 insertions(+), 55 deletions(-) diff --git a/xLights/models/ModelGroup.h b/xLights/models/ModelGroup.h index 173a14da20..7829da5de7 100644 --- a/xLights/models/ModelGroup.h +++ b/xLights/models/ModelGroup.h @@ -15,6 +15,7 @@ #include #include "Model.h" +#include "Color.h" class ModelManager; @@ -88,6 +89,12 @@ class ModelGroup : public ModelWithScreenLocation void SetCentreMiny( int miny ); void SetCentreMaxx( int maxx ); void SetCentreMaxy( int maxy ); + int GetCentreMinx() const { return minx; } + int GetCentreMiny() const { return miny; } + int GetCentreMaxx() const { return maxx; } + int GetCentreMaxy() const { return maxy; } + std::string GetLayout() const { return layout_group; } + wxColour GetTagColour() const { return modelTagColour; } protected: static std::vector GROUP_BUFFER_STYLES; @@ -102,5 +109,9 @@ class ModelGroup : public ModelWithScreenLocation bool centreDefined = false; float centrex; float centrey; + int minx = 0; + int miny = 0; + int maxx = 0; + int maxy = 0; }; diff --git a/xLights/models/SubModel.h b/xLights/models/SubModel.h index 03820ecbb2..b711d79b9c 100644 --- a/xLights/models/SubModel.h +++ b/xLights/models/SubModel.h @@ -63,7 +63,12 @@ class SubModel : public Model { [[nodiscard]] FaceStateData const& GetFaceInfo() const override { return parent->faceInfo; }; [[nodiscard]] FaceStateNodes const& GetFaceInfoNodes() const override { return parent->faceInfoNodes; }; -private: + std::string GetSubModelLayout() const { return _layout; } + std::string GetSubModelType() const { return _type; } + std::string GetSubModelBufferStyle() const { return _bufferStyle; } + std::string GetSubModelNodeRanges() const { return _properyGridDisplay; } + + private: void CheckDuplicates(const std::vector& nodeIndexes); Model *parent = nullptr; diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index a8ecbe228c..e008def1b0 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -23,6 +23,8 @@ #include "IciclesModel.h" #include "ImageModel.h" #include "MatrixModel.h" +#include "Model.h" +#include "ModelGroup.h" #include "PolyLineModel.h" #include "SingleLineModel.h" #include "SphereModel.h" @@ -69,6 +71,7 @@ namespace XmlNodeKeys { constexpr auto ActiveAttribute = "Active"; constexpr auto FromBaaseAttribute = "FromBase"; constexpr auto DescriptionAttribute = "Description"; + constexpr auto CustomStringsAttribute = "String"; // Common SubModel Attributes constexpr auto SubModelNodeName = "subModel"; @@ -77,9 +80,9 @@ namespace XmlNodeKeys { constexpr auto SMTypeAttribute = "type"; constexpr auto BufferStyleAttribute = "bufferstyle"; constexpr auto SubBufferStyleAttribute = "subBuffer"; - constexpr auto Line0Attribute = "line0"; + constexpr auto LineAttribute = "line"; - // aliases) { + wxXmlNode* aliashdr = new wxXmlNode(wxXML_ELEMENT_NODE, "Aliases"); + + for (const auto& a : aliases) { + wxXmlNode* alias = new wxXmlNode(wxXML_ELEMENT_NODE, "alias"); + alias->AddAttribute("name", a); + aliashdr->AddChild(alias); + } + node->AddChild(aliashdr); + } + + void AddSubmodels(wxXmlNode* node, const std::string name, const Model* sm) { + const SubModel* sm0 = dynamic_cast(sm); wxXmlNode* submodels = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::SubModelNodeName); submodels->AddAttribute(XmlNodeKeys::SubModelNameAttribute, sm->GetName()); const std::list& aliases = sm->GetAliases(); - // const Model* m = dynamic_cast(sm); - // const ModelManager& mgr = m->GetModelManager(); - - submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, "foo"); - submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, "bar"); - submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, "baz"); - submodels->AddAttribute(XmlNodeKeys::SubBufferStyleAttribute, "foobarbaz"); - submodels->AddAttribute(XmlNodeKeys::Line0Attribute, "foobarbaz"); + submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, sm0->GetSubModelLayout()); + submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, sm0->GetSubModelType()); + + const std::string submodelBufferStyle = sm0->GetSubModelBufferStyle(); + if (submodelBufferStyle == "bufferstyle") { + submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, submodelBufferStyle); + } else { + wxArrayString nodeInfo = wxSplit(sm0->GetSubModelNodeRanges(), ','); + for (auto i = 0; i < nodeInfo.size(); i++) { + submodels->AddAttribute("line" + std::to_string(i), nodeInfo[i]); + } + } AddAliases(submodels, aliases); node->AddChild(submodels); } - void AddGroups(wxXmlNode* node, std::vector groups, const std::string name) { - for (const auto& g : groups) { + void AddGroups(wxXmlNode* node, const std::string name, const Model* m) { + const ModelManager& mgr = m->GetModelManager(); + std::vector mg = mgr.GetModelGroups(m); + + for (const Model* g : mg) { + const ModelGroup* mg1 = dynamic_cast(g); wxXmlNode* groups = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::GroupNodeName); - groups->AddAttribute(XmlNodeKeys::mgNameAttribute, g); + groups->AddAttribute(XmlNodeKeys::mgNameAttribute, g->GetName()); groups->AddAttribute(XmlNodeKeys::mgModelsAttribute, name); - groups->AddAttribute(XmlNodeKeys::mgLayoutGroupAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgSelectedAttribute, "foo"); - groups->AddAttribute(XmlNodeKeys::mgLayoutAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgGridSizeAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgTagColourAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentreMinxAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentreMinyAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentreMaxxAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentreMaxyAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentrexAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentreyAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgCentreDefinedAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgDefaultCameraAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgxCentreOffsetAttribute, "foobarbaz"); - groups->AddAttribute(XmlNodeKeys::mgyCentreOffsetAttribute, "foobarbaz"); + groups->AddAttribute(XmlNodeKeys::mgLayoutGroupAttribute, g->GetLayoutGroup()); + groups->AddAttribute(XmlNodeKeys::mgSelectedAttribute, std::to_string(mg1->IsSelected())); + groups->AddAttribute(XmlNodeKeys::mgLayoutAttribute, mg1->GetLayout()); + groups->AddAttribute(XmlNodeKeys::mgGridSizeAttribute, std::to_string(mg1->GetGridSize())); + groups->AddAttribute(XmlNodeKeys::mgTagColourAttribute, mg1->GetTagColour().GetAsString(wxC2S_HTML_SYNTAX)); + groups->AddAttribute(XmlNodeKeys::mgCentreMinxAttribute, std::to_string(mg1->GetCentreMinx())); + groups->AddAttribute(XmlNodeKeys::mgCentreMinyAttribute, std::to_string(mg1->GetCentreMiny())); + groups->AddAttribute(XmlNodeKeys::mgCentreMaxxAttribute, std::to_string(mg1->GetCentreMaxx())); + groups->AddAttribute(XmlNodeKeys::mgCentreMaxyAttribute, std::to_string(mg1->GetCentreMaxy())); + groups->AddAttribute(XmlNodeKeys::mgCentrexAttribute, std::to_string(mg1->GetCentreX())); + groups->AddAttribute(XmlNodeKeys::mgCentreyAttribute, std::to_string(mg1->GetCentreY())); + groups->AddAttribute(XmlNodeKeys::mgCentreDefinedAttribute, std::to_string(mg1->GetCentreDefined())); + groups->AddAttribute(XmlNodeKeys::mgDefaultCameraAttribute, mg1->GetDefaultCamera()); + groups->AddAttribute(XmlNodeKeys::mgxCentreOffsetAttribute, std::to_string(mg1->GetXCentreOffset())); + groups->AddAttribute(XmlNodeKeys::mgyCentreOffsetAttribute, std::to_string(mg1->GetYCentreOffset())); // AddAliases(groups,aliases); node->AddChild(groups); } } - void AddAliases(wxXmlNode* node, const std::list aliases) { - wxXmlNode* aliashdr = new wxXmlNode(wxXML_ELEMENT_NODE, "Aliases"); - - for (const auto& a : aliases) { - wxXmlNode* alias = new wxXmlNode(wxXML_ELEMENT_NODE, "alias"); - alias->AddAttribute("name", a); - aliashdr->AddChild(alias); - } - node->AddChild(aliashdr); - } - void Visit(const ArchesModel& arch) override { wxXmlNode* archNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); @@ -584,9 +596,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { const std::string name = arch.GetName(); const Model* m = dynamic_cast(&arch); - const ModelManager& mgr = m->GetModelManager(); - std::vector groups = mgr.GetGroupsContainingModel(m); - std::vector modelGroups = mgr.GetModelGroups(m); AddBaseObjectAttributes(arch, archNode); AddCommonModelAttributes(arch, archNode); @@ -599,9 +608,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddAliases(archNode, aliases); for (Model* submodel : submodels) { Model* sm = arch.GetSubModel(submodel->GetName()); - AddSubmodels(archNode, sm); + AddSubmodels(archNode, name, sm); } - AddGroups(archNode, groups, name); + AddGroups(archNode, name, m); parentNode->AddChild(archNode); } @@ -613,8 +622,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { const std::string name = cc.GetName(); const Model* m = dynamic_cast(&cc); - const ModelManager& mgr = m->GetModelManager(); - std::vector groups = mgr.GetGroupsContainingModel(m); AddBaseObjectAttributes(cc, ccNode); AddCommonModelAttributes(cc, ccNode); @@ -623,9 +630,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddAliases(ccNode, aliases); for (Model* submodel : submodels) { Model* sm = cc.GetSubModel(submodel->GetName()); - AddSubmodels(ccNode, sm); + AddSubmodels(ccNode, name, sm); } - AddGroups(ccNode, groups, name); + AddGroups(ccNode, name, m); parentNode->AddChild(ccNode); } @@ -637,8 +644,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { const std::string name = circle.GetName(); const Model* m = dynamic_cast(&circle); - const ModelManager& mgr = m->GetModelManager(); - std::vector groups = mgr.GetGroupsContainingModel(m); AddBaseObjectAttributes(circle, circleNode); AddCommonModelAttributes(circle, circleNode); @@ -647,9 +652,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddAliases(circleNode, aliases); for (Model* submodel : submodels) { Model* sm = circle.GetSubModel(submodel->GetName()); - AddSubmodels(circleNode, sm); + AddSubmodels(circleNode, name, sm); } - AddGroups(circleNode, groups, name); + AddGroups(circleNode, name, m); parentNode->AddChild(circleNode); } From d67c5b8dadb2a415008a7e69daf62e8d4afa4644 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 8 May 2024 00:33:01 -0400 Subject: [PATCH 03/17] XMLSerializer with visitor WIP --- xLights/models/XmlSerializer.h | 381 +++++++++++++++++---------------- 1 file changed, 191 insertions(+), 190 deletions(-) diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index e008def1b0..8759a8402f 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -42,88 +42,88 @@ namespace XmlNodeKeys { // Model Node Names - constexpr auto ModelsNodeName = "models"; - constexpr auto ModelNodeName = "model"; - constexpr auto TypeAttribute = "type"; + constexpr auto ModelsNodeName = "models"; + constexpr auto ModelNodeName = "model"; + constexpr auto TypeAttribute = "type"; constexpr auto ExportedAttribute = "exported"; // Common BaseObject Attributes - constexpr auto NameAttribute = "name"; - constexpr auto DisplayAsAttribute = "DisplayAs"; + constexpr auto NameAttribute = "name"; + constexpr auto DisplayAsAttribute = "DisplayAs"; constexpr auto LayoutGroupAttribute = "LayoutGroup"; // Common Model Attributes - constexpr auto StartSideAttribute = "StartSide"; - constexpr auto DirAttribute = "Dir"; - constexpr auto Parm1Attribute = "parm1"; - constexpr auto Parm2Attribute = "parm2"; - constexpr auto Parm3Attribute = "parm3"; - constexpr auto AntialiasAttribute = "Antialias"; - constexpr auto PixelSizeAttribute = "PixelSize"; - constexpr auto StringTypeAttribute = "StringType"; - constexpr auto TransparencyAttribute = "Transparency"; + constexpr auto StartSideAttribute = "StartSide"; + constexpr auto DirAttribute = "Dir"; + constexpr auto Parm1Attribute = "parm1"; + constexpr auto Parm2Attribute = "parm2"; + constexpr auto Parm3Attribute = "parm3"; + constexpr auto AntialiasAttribute = "Antialias"; + constexpr auto PixelSizeAttribute = "PixelSize"; + constexpr auto StringTypeAttribute = "StringType"; + constexpr auto TransparencyAttribute = "Transparency"; constexpr auto BTransparencyAttribute = "BlackTransparency"; - constexpr auto StartChannelAttribute = "StartChannel"; - constexpr auto NodeNamesAttribute = "NodeNames"; - constexpr auto StrandNamesAttribute = "StrandNames"; - constexpr auto ControllerAttribute = "Controller"; + constexpr auto StartChannelAttribute = "StartChannel"; + constexpr auto NodeNamesAttribute = "NodeNames"; + constexpr auto StrandNamesAttribute = "StrandNames"; + constexpr auto ControllerAttribute = "Controller"; constexpr auto versionNumberAttribute = "versionNumber"; - constexpr auto ActiveAttribute = "Active"; - constexpr auto FromBaaseAttribute = "FromBase"; - constexpr auto DescriptionAttribute = "Description"; + constexpr auto ActiveAttribute = "Active"; + constexpr auto FromBaaseAttribute = "FromBase"; + constexpr auto DescriptionAttribute = "Description"; constexpr auto CustomStringsAttribute = "String"; // Common SubModel Attributes - constexpr auto SubModelNodeName = "subModel"; - constexpr auto SubModelNameAttribute = "name"; - constexpr auto LayoutAttribute = "layout"; - constexpr auto SMTypeAttribute = "type"; - constexpr auto BufferStyleAttribute = "bufferstyle"; + constexpr auto SubModelNodeName = "subModel"; + constexpr auto SubModelNameAttribute = "name"; + constexpr auto LayoutAttribute = "layout"; + constexpr auto SMTypeAttribute = "type"; + constexpr auto BufferStyleAttribute = "bufferstyle"; constexpr auto SubBufferStyleAttribute = "subBuffer"; - constexpr auto LineAttribute = "line"; + constexpr auto LineAttribute = "line"; // ModelGroup - constexpr auto GroupNodeName = "modelGroup"; - constexpr auto mgSelectedAttribute = "selected"; - constexpr auto mgLayoutAttribute = "layout"; - constexpr auto mgGridSizeAttribute = "GridSize"; - constexpr auto mgLayoutGroupAttribute = "LayoutGroup"; - constexpr auto mgNameAttribute = "name"; - constexpr auto mgCentreMinxAttribute = "centreMinx"; - constexpr auto mgCentreMinyAttribute = "centreMiny"; - constexpr auto mgCentreMaxxAttribute = "centreMaxx"; - constexpr auto mgCentreMaxyAttribute = "centreMaxy"; - constexpr auto mgModelsAttribute = "models"; - constexpr auto mgCentrexAttribute = "centrex"; - constexpr auto mgCentreyAttribute = "centrey"; + constexpr auto GroupNodeName = "modelGroup"; + constexpr auto mgSelectedAttribute = "selected"; + constexpr auto mgLayoutAttribute = "layout"; + constexpr auto mgGridSizeAttribute = "GridSize"; + constexpr auto mgLayoutGroupAttribute = "LayoutGroup"; + constexpr auto mgNameAttribute = "name"; + constexpr auto mgCentreMinxAttribute = "centreMinx"; + constexpr auto mgCentreMinyAttribute = "centreMiny"; + constexpr auto mgCentreMaxxAttribute = "centreMaxx"; + constexpr auto mgCentreMaxyAttribute = "centreMaxy"; + constexpr auto mgModelsAttribute = "models"; + constexpr auto mgCentrexAttribute = "centrex"; + constexpr auto mgCentreyAttribute = "centrey"; constexpr auto mgCentreDefinedAttribute = "centreDefined"; constexpr auto mgxCentreOffsetAttribute = "XCentreOffset"; constexpr auto mgyCentreOffsetAttribute = "YCentreOffset"; constexpr auto mgDefaultCameraAttribute = "DefaultCamera"; - constexpr auto mgTagColourAttribute = "TagColour"; + constexpr auto mgTagColourAttribute = "TagColour"; // Size/Position Attributes constexpr auto WorldPosXAttribute = "WorldPosX"; constexpr auto WorldPosYAttribute = "WorldPosY"; constexpr auto WorldPosZAttribute = "WorldPosZ"; - constexpr auto ScaleXAttribute = "ScaleX"; - constexpr auto ScaleYAttribute = "ScaleY"; - constexpr auto ScaleZAttribute = "ScaleZ"; - constexpr auto RotateXAttribute = "RotateX"; - constexpr auto RotateYAttribute = "RotateY"; - constexpr auto RotateZAttribute = "RotateZ"; - constexpr auto WidthAttribute = "Width"; - constexpr auto HeightAttribute = "Height"; - constexpr auto DepthAttribute = "Depth"; - constexpr auto OffsetXAttribute = "OffsetX"; - constexpr auto OffsetYAttribute = "OffsetY"; - constexpr auto OffsetZAttribute = "OffsetZ"; + constexpr auto ScaleXAttribute = "ScaleX"; + constexpr auto ScaleYAttribute = "ScaleY"; + constexpr auto ScaleZAttribute = "ScaleZ"; + constexpr auto RotateXAttribute = "RotateX"; + constexpr auto RotateYAttribute = "RotateY"; + constexpr auto RotateZAttribute = "RotateZ"; + constexpr auto WidthAttribute = "Width"; + constexpr auto HeightAttribute = "Height"; + constexpr auto DepthAttribute = "Depth"; + constexpr auto OffsetXAttribute = "OffsetX"; + constexpr auto OffsetYAttribute = "OffsetY"; + constexpr auto OffsetZAttribute = "OffsetZ"; // Dimentions Attributes - constexpr auto DimUnitsAttribute = "units"; - constexpr auto DimWidthAttribute = "width"; + constexpr auto DimUnitsAttribute = "units"; + constexpr auto DimWidthAttribute = "width"; constexpr auto DimHeightAttribute = "height"; - constexpr auto DimDepthAttribute = "depth"; + constexpr auto DimDepthAttribute = "depth"; // Model Screen Location Attributes constexpr auto LockedAttribute = "Locked"; @@ -138,74 +138,74 @@ namespace XmlNodeKeys { constexpr auto ShearAttribute = "Shear"; // DmxColorAbilityRGB Attributes - constexpr auto DmxRedChannelAttribute = "DmxRedChannel"; + constexpr auto DmxRedChannelAttribute = "DmxRedChannel"; constexpr auto DmxGreenChannelAttribute = "DmxGreenChannel"; - constexpr auto DmxBlueChannelAttribute = "DmxBlueChannel"; + constexpr auto DmxBlueChannelAttribute = "DmxBlueChannel"; constexpr auto DmxWhiteChannelAttribute = "DmxWhiteChannel"; // DmxColorAbilityWheel Attributes constexpr auto DmxColorWheelChannelAttribute = "DmxColorWheelChannel"; - constexpr auto DmxDimmerChannelAttribute = "DmxDimmerChannel"; - constexpr auto DmxColorWheelColorAttribute = "DmxColorWheelColor"; - constexpr auto DmxColorWheelDMXAttribute = "DmxColorWheelDMX"; + constexpr auto DmxDimmerChannelAttribute = "DmxDimmerChannel"; + constexpr auto DmxColorWheelColorAttribute = "DmxColorWheelColor"; + constexpr auto DmxColorWheelDMXAttribute = "DmxColorWheelDMX"; // DmxColorAbilityCMY Attributes - constexpr auto DmxCyanChannelAttribute = "DmxCyanChannel"; + constexpr auto DmxCyanChannelAttribute = "DmxCyanChannel"; constexpr auto DmxMagentaChannelAttribute = "DmxMagentaChannel"; - constexpr auto DmxYellowChannelAttribute = "DmxYellowChannel"; + constexpr auto DmxYellowChannelAttribute = "DmxYellowChannel"; // DmxMovingHeadComm Attributes constexpr auto DmxFixturelAttribute = "DmxFixture"; // DMX Moving Head Attributes - constexpr auto DmxColorTypeAttribute = "DmxColorType"; + constexpr auto DmxColorTypeAttribute = "DmxColorType"; constexpr auto DmxBeamYOffsetAttribute = "DmxBeamYOffset"; - constexpr auto DmxBeamLengthAttribute = "DmxBeamLength"; + constexpr auto DmxBeamLengthAttribute = "DmxBeamLength"; // DmxMotor Attributes constexpr auto ChannelCoarseAttribute = "ChannelCoarse"; - constexpr auto ChannelFineAttribute = "ChannelFine"; - constexpr auto MinLimitAttribute = "MinLimit"; - constexpr auto MaxLimitAttribute = "MaxLimit"; + constexpr auto ChannelFineAttribute = "ChannelFine"; + constexpr auto MinLimitAttribute = "MinLimit"; + constexpr auto MaxLimitAttribute = "MaxLimit"; constexpr auto RangeOfMotionAttribute = "RangeOfMotion"; - constexpr auto OrientZeroAttribute = "OrientZero"; - constexpr auto OrientHomeAttribute = "OrientHome"; - constexpr auto SlewLimitAttribute = "SlewLimit"; - constexpr auto ReverseAttribute = "Reverse"; - constexpr auto UpsideDownAttribute = "UpsideDown"; + constexpr auto OrientZeroAttribute = "OrientZero"; + constexpr auto OrientHomeAttribute = "OrientHome"; + constexpr auto SlewLimitAttribute = "SlewLimit"; + constexpr auto ReverseAttribute = "Reverse"; + constexpr auto UpsideDownAttribute = "UpsideDown"; // Servo Model // TBC // Controller constexpr auto ConnectionAttribute = "Connection"; - constexpr auto ProtocolAttribute = "Protocol"; - constexpr auto PortAttribute = "Port"; - constexpr auto StartNullAttribute = "startNull"; - constexpr auto EndNullAttribute = "endNull"; + constexpr auto ProtocolAttribute = "Protocol"; + constexpr auto PortAttribute = "Port"; + constexpr auto StartNullAttribute = "startNull"; + constexpr auto EndNullAttribute = "endNull"; // Arch Attributes constexpr auto ZigZagAttribute = "ZigZag"; constexpr auto HollowAttribute = "Hollow"; - constexpr auto GapAttribute = "Gap"; + constexpr auto GapAttribute = "Gap"; // Mesh Attributes - constexpr auto ObjFileAttribute = "ObjFile"; - constexpr auto MeshOnlyAttribute = "MeshOnly"; + constexpr auto ObjFileAttribute = "ObjFile"; + constexpr auto MeshOnlyAttribute = "MeshOnly"; constexpr auto BrightnessAttribute = "Brightness"; // Arch, CandyCane, Icicles, Single Line Models // Channel Block Model - constexpr auto ChannelPropertiesCC1Attribute = "ChannelProperties.ChannelColor1"; - constexpr auto ChannelPropertiesCC2Attribute = "ChannelProperties.ChannelColor2"; - constexpr auto ChannelPropertiesCC3Attribute = "ChannelProperties.ChannelColor3"; - constexpr auto ChannelPropertiesCC4Attribute = "ChannelProperties.ChannelColor4"; - constexpr auto ChannelPropertiesCC5Attribute = "ChannelProperties.ChannelColor5"; - constexpr auto ChannelPropertiesCC6Attribute = "ChannelProperties.ChannelColor6"; - constexpr auto ChannelPropertiesCC7Attribute = "ChannelProperties.ChannelColor7"; - constexpr auto ChannelPropertiesCC8Attribute = "ChannelProperties.ChannelColor8"; - constexpr auto ChannelPropertiesCC9Attribute = "ChannelProperties.ChannelColor9"; + constexpr auto ChannelPropertiesCC1Attribute = "ChannelProperties.ChannelColor1"; + constexpr auto ChannelPropertiesCC2Attribute = "ChannelProperties.ChannelColor2"; + constexpr auto ChannelPropertiesCC3Attribute = "ChannelProperties.ChannelColor3"; + constexpr auto ChannelPropertiesCC4Attribute = "ChannelProperties.ChannelColor4"; + constexpr auto ChannelPropertiesCC5Attribute = "ChannelProperties.ChannelColor5"; + constexpr auto ChannelPropertiesCC6Attribute = "ChannelProperties.ChannelColor6"; + constexpr auto ChannelPropertiesCC7Attribute = "ChannelProperties.ChannelColor7"; + constexpr auto ChannelPropertiesCC8Attribute = "ChannelProperties.ChannelColor8"; + constexpr auto ChannelPropertiesCC9Attribute = "ChannelProperties.ChannelColor9"; constexpr auto ChannelPropertiesCC10Attribute = "ChannelProperties.ChannelColor10"; constexpr auto ChannelPropertiesCC11Attribute = "ChannelProperties.ChannelColor11"; constexpr auto ChannelPropertiesCC12Attribute = "ChannelProperties.ChannelColor12"; @@ -218,20 +218,20 @@ namespace XmlNodeKeys { constexpr auto InsideOutAttribute = "InsideOut"; // Cube - constexpr auto StyleAttribute = "Style"; + constexpr auto StyleAttribute = "Style"; constexpr auto StrandPerLineAttribute = "SrtrandPerLine"; // Custom Model - constexpr auto CustomModel = "Custom"; + constexpr auto CustomModel = "Custom"; constexpr auto CMBrightnessAttribute = "Brightness"; - constexpr auto StrandsAttribute = "Strands"; - constexpr auto NodesAttribute = "Nodes"; - constexpr auto PixelCountAttribute = "PixelCount"; - constexpr auto PixelTypeAttribute = "PixelType"; + constexpr auto StrandsAttribute = "Strands"; + constexpr auto NodesAttribute = "Nodes"; + constexpr auto PixelCountAttribute = "PixelCount"; + constexpr auto PixelTypeAttribute = "PixelType"; constexpr auto PixelSpacingAttribute = "PixelSpacing"; - constexpr auto PixelAttribute = "Pixel"; + constexpr auto PixelAttribute = "Pixel"; constexpr auto BkgLightnessAttribute = "BkgLightness"; - constexpr auto BkgAttribute = "Bkg"; + constexpr auto BkgAttribute = "Bkg"; // Image Model constexpr auto ImageAttribute = "Image"; @@ -242,98 +242,98 @@ namespace XmlNodeKeys { constexpr auto DropPatternAttribute = "DropPattern"; // Poly Line Model - constexpr auto NumPointsAttribute = "NumPoints"; - constexpr auto PointDataAttribute = "PointData"; - constexpr auto cPointDataAttribute = "cPointData"; - constexpr auto IndivegAttribute = "Indiveg"; + constexpr auto NumPointsAttribute = "NumPoints"; + constexpr auto PointDataAttribute = "PointData"; + constexpr auto cPointDataAttribute = "cPointData"; + constexpr auto IndivegAttribute = "Indiveg"; constexpr auto SegExpandedAttribute = "SegExpanded"; - constexpr auto SegAttribute = "Seg"; // needs fix Seg1, Seg2, Seg3 - constexpr auto CornerAttribute = "Corner"; // needs fix Corner1, Corner2, Corner3 + constexpr auto SegAttribute = "Seg"; // needs fix Seg1, Seg2, Seg3 + constexpr auto CornerAttribute = "Corner"; // needs fix Corner1, Corner2, Corner3 // Spinner Model - constexpr auto ArcAttribute = "Arc"; - constexpr auto StringAttribute = "String"; + constexpr auto ArcAttribute = "Arc"; + constexpr auto StringAttribute = "String"; constexpr auto AlternateAttribute = "Alternate"; - constexpr auto StartAttribute = "Start"; + constexpr auto StartAttribute = "Start"; // Star Model constexpr auto StarStartLocationAttribute = "StarStartLocation"; - constexpr auto LayerSizesAttribute = "LayerSizes"; - constexpr auto TagColourAttribute = "TagColour"; + constexpr auto LayerSizesAttribute = "LayerSizes"; + constexpr auto TagColourAttribute = "TagColour"; // Tree Model constexpr auto TreeBottomTopRatioAttribute = "TreeBottomTopRatio"; - constexpr auto TreePerspectiveAttribute = "TreePerspective"; - constexpr auto TreeAttribute = "Tree"; - constexpr auto TreeSpiralsAttribute = "TreeSpirals"; + constexpr auto TreePerspectiveAttribute = "TreePerspective"; + constexpr auto TreeAttribute = "Tree"; + constexpr auto TreeSpiralsAttribute = "TreeSpirals"; // Window Frame Model constexpr auto RotationAttribute = "Rotation"; // States - constexpr auto StateAttribute = "stateInfo"; + constexpr auto StateAttribute = "stateInfo"; constexpr auto ColorsAttribute = "Colors"; - constexpr auto sAttribute = "s"; // needs enumeration s1, s2, s3 etc - constexpr auto sColorAttribute = "sColor"; // needs enumeration s1-Color s2-Color, s3-Color etc - constexpr auto sNameAttribute = "sName"; // needs enumeration s1-Name s2-Name, s3-Name etc + constexpr auto sAttribute = "s"; // needs enumeration s1, s2, s3 etc + constexpr auto sColorAttribute = "sColor"; // needs enumeration s1-Color s2-Color, s3-Color etc + constexpr auto sNameAttribute = "sName"; // needs enumeration s1-Name s2-Name, s3-Name etc // Faces - constexpr auto EyesClosedAttribute = "Eyes - Closed"; - constexpr auto EyesClosedColorAttribute = "Eyes - Closed - Color"; - constexpr auto EyesClosed2Attribute = "Eyes - Closed2"; - constexpr auto EyesClosed2ColorAttribute = "Eyes - Closed2 - Color"; - constexpr auto EyesClosed3Attribute = "Eyes - Closed3"; - constexpr auto EyesClosed3ColorAttribute = "Eyes - Closed3 - Color"; - constexpr auto EyesOpenAttribute = "Eyes - Open"; - constexpr auto EyesOpenColorAttribute = "Eyes - Open - Color"; - constexpr auto EyesOpen2Attribute = "Eyes - Open2"; - constexpr auto EyesOpen2ColorAttribute = "Eyes - Open2 - Color"; - constexpr auto EyesOpen3Attribute = "Eyes - Open3"; - constexpr auto EyesOpen3ColorAttribute = "Eyes - Open3 - Color"; - constexpr auto FaceOutlineAttribute = "FaceOutline"; - constexpr auto FaceOutlineColorAttribute = "FaceOutline - Color"; - constexpr auto FaceOutline2Attribute = "FaceOutline2"; + constexpr auto EyesClosedAttribute = "Eyes - Closed"; + constexpr auto EyesClosedColorAttribute = "Eyes - Closed - Color"; + constexpr auto EyesClosed2Attribute = "Eyes - Closed2"; + constexpr auto EyesClosed2ColorAttribute = "Eyes - Closed2 - Color"; + constexpr auto EyesClosed3Attribute = "Eyes - Closed3"; + constexpr auto EyesClosed3ColorAttribute = "Eyes - Closed3 - Color"; + constexpr auto EyesOpenAttribute = "Eyes - Open"; + constexpr auto EyesOpenColorAttribute = "Eyes - Open - Color"; + constexpr auto EyesOpen2Attribute = "Eyes - Open2"; + constexpr auto EyesOpen2ColorAttribute = "Eyes - Open2 - Color"; + constexpr auto EyesOpen3Attribute = "Eyes - Open3"; + constexpr auto EyesOpen3ColorAttribute = "Eyes - Open3 - Color"; + constexpr auto FaceOutlineAttribute = "FaceOutline"; + constexpr auto FaceOutlineColorAttribute = "FaceOutline - Color"; + constexpr auto FaceOutline2Attribute = "FaceOutline2"; constexpr auto FaceOutline2ColorAttribute = "FaceOutline2 - Color"; - constexpr auto MouthAIAttribute = "Mouth - AI"; - constexpr auto MouthEAttribute = "Mouth - E"; - constexpr auto MouthFVAttribute = "Mouth - FV"; - constexpr auto MouthLAttribute = "Mouth - L"; - constexpr auto MouthMBPAttribute = "Mouth - MBP"; - constexpr auto MouthOAttribute = "Mouth - O"; - constexpr auto MouthUAttribute = "Mouth - U"; - constexpr auto MouthWQAttribute = "Mouth - WQ"; - constexpr auto MouthetcAttribute = "Mouth - etc"; - constexpr auto MouthretAttribute = "Mouth - rest"; - constexpr auto MouthAIColorAttribute = "Mouth - AI-Color"; - constexpr auto MouthEColorAttribute = "Mouth - E-Color"; - constexpr auto MouthFVColorAttribute = "Mouth - FV-Color"; - constexpr auto MouthLColorAttribute = "Mouth - L-Color"; - constexpr auto MouthMBPColorAttribute = "Mouth - MBP-Color"; - constexpr auto MouthOColorAttribute = "Mouth - O-Color"; - constexpr auto MouthUColorAttribute = "Mouth - U-Color"; - constexpr auto MouthWQColorAttribute = "Mouth - WQ-Color"; - constexpr auto MouthetcColorAttribute = "Mouth - etc-Color"; - constexpr auto MouthrestColorAttribute = "Mouth - rest-Color"; - constexpr auto MouthAI2Attribute = "Mouth - AI2"; - constexpr auto MouthE2Attribute = "Mouth - E2"; - constexpr auto MouthFV2Attribute = "Mouth - FV2"; - constexpr auto MouthL2Attribute = "Mouth - L2"; - constexpr auto MouthMBP2Attribute = "Mouth - MBP2"; - constexpr auto MouthO2Attribute = "Mouth - O2"; - constexpr auto MouthU2Attribute = "Mouth - U2"; - constexpr auto MouthWQ2Attribute = "Mouth - WQ2"; - constexpr auto Mouthetc2Attribute = "Mouth - etc2"; - constexpr auto Mouthret2Attribute = "Mouth - rest2"; - constexpr auto MouthAIColor2Attribute = "Mouth - AI2-Color"; - constexpr auto MouthEColor2Attribute = "Mouth - E2-Color"; - constexpr auto MouthFVColor2Attribute = "Mouth - FV2-Color"; - constexpr auto MouthLColor2Attribute = "Mouth - L2-Color"; - constexpr auto MouthMBPColor2Attribute = "Mouth - MBP2-Color"; - constexpr auto MouthOColor2Attribute = "Mouth - O2-Color"; - constexpr auto MouthUColor2Attribute = "Mouth - U2-Color"; - constexpr auto MouthWQColor2Attribute = "Mouth - WQ2-Color"; - constexpr auto MouthetcColor2Attribute = "Mouth - etc2-Color"; - constexpr auto MouthrestColor2Attribute = "Mouth - rest2-Color"; + constexpr auto MouthAIAttribute = "Mouth - AI"; + constexpr auto MouthEAttribute = "Mouth - E"; + constexpr auto MouthFVAttribute = "Mouth - FV"; + constexpr auto MouthLAttribute = "Mouth - L"; + constexpr auto MouthMBPAttribute = "Mouth - MBP"; + constexpr auto MouthOAttribute = "Mouth - O"; + constexpr auto MouthUAttribute = "Mouth - U"; + constexpr auto MouthWQAttribute = "Mouth - WQ"; + constexpr auto MouthetcAttribute = "Mouth - etc"; + constexpr auto MouthretAttribute = "Mouth - rest"; + constexpr auto MouthAIColorAttribute = "Mouth - AI-Color"; + constexpr auto MouthEColorAttribute = "Mouth - E-Color"; + constexpr auto MouthFVColorAttribute = "Mouth - FV-Color"; + constexpr auto MouthLColorAttribute = "Mouth - L-Color"; + constexpr auto MouthMBPColorAttribute = "Mouth - MBP-Color"; + constexpr auto MouthOColorAttribute = "Mouth - O-Color"; + constexpr auto MouthUColorAttribute = "Mouth - U-Color"; + constexpr auto MouthWQColorAttribute = "Mouth - WQ-Color"; + constexpr auto MouthetcColorAttribute = "Mouth - etc-Color"; + constexpr auto MouthrestColorAttribute = "Mouth - rest-Color"; + constexpr auto MouthAI2Attribute = "Mouth - AI2"; + constexpr auto MouthE2Attribute = "Mouth - E2"; + constexpr auto MouthFV2Attribute = "Mouth - FV2"; + constexpr auto MouthL2Attribute = "Mouth - L2"; + constexpr auto MouthMBP2Attribute = "Mouth - MBP2"; + constexpr auto MouthO2Attribute = "Mouth - O2"; + constexpr auto MouthU2Attribute = "Mouth - U2"; + constexpr auto MouthWQ2Attribute = "Mouth - WQ2"; + constexpr auto Mouthetc2Attribute = "Mouth - etc2"; + constexpr auto Mouthret2Attribute = "Mouth - rest2"; + constexpr auto MouthAIColor2Attribute = "Mouth - AI2-Color"; + constexpr auto MouthEColor2Attribute = "Mouth - E2-Color"; + constexpr auto MouthFVColor2Attribute = "Mouth - FV2-Color"; + constexpr auto MouthLColor2Attribute = "Mouth - L2-Color"; + constexpr auto MouthMBPColor2Attribute = "Mouth - MBP2-Color"; + constexpr auto MouthOColor2Attribute = "Mouth - O2-Color"; + constexpr auto MouthUColor2Attribute = "Mouth - U2-Color"; + constexpr auto MouthWQColor2Attribute = "Mouth - WQ2-Color"; + constexpr auto MouthetcColor2Attribute = "Mouth - etc2-Color"; + constexpr auto MouthrestColor2Attribute = "Mouth - rest2-Color"; // WIP // constexpr auto Attribute = ""; @@ -355,26 +355,26 @@ namespace XmlNodeKeys { // ViewPoint // Model Types - constexpr auto ArchesType = "Arches"; - constexpr auto CandyCaneType = "Candy Canes"; - constexpr auto ChannelBlockType = "Channel Block"; - constexpr auto CircleType = "Circle"; - constexpr auto CubeType = "Cube"; - constexpr auto CustomType = "Custom"; + constexpr auto ArchesType = "Arches"; + constexpr auto CandyCaneType = "Candy Canes"; + constexpr auto ChannelBlockType = "Channel Block"; + constexpr auto CircleType = "Circle"; + constexpr auto CubeType = "Cube"; + constexpr auto CustomType = "Custom"; constexpr auto DmxMovingHeadAdvType = "DmxMovingHeadAdv"; - constexpr auto IciclesType = "Icicles"; - constexpr auto ImageType = "Image"; - constexpr auto MatrixType = "Matrix"; - constexpr auto SingleLineType = "Single Line"; - constexpr auto PolyLineType = "Poly Line"; - constexpr auto SphereType = "Sphere"; - constexpr auto SpinnerType = "Spinner"; - constexpr auto StarType = "Star"; - constexpr auto Tree360Type = "Tree 360"; - constexpr auto TreeFlatType = "Tree Flat"; - constexpr auto TreeRibbonType = "Tree Ribbon"; - constexpr auto WindowType = "Window Frame"; - constexpr auto WreathType = "Wreath"; + constexpr auto IciclesType = "Icicles"; + constexpr auto ImageType = "Image"; + constexpr auto MatrixType = "Matrix"; + constexpr auto SingleLineType = "Single Line"; + constexpr auto PolyLineType = "Poly Line"; + constexpr auto SphereType = "Sphere"; + constexpr auto SpinnerType = "Spinner"; + constexpr auto StarType = "Star"; + constexpr auto Tree360Type = "Tree 360"; + constexpr auto TreeFlatType = "Tree Flat"; + constexpr auto TreeRibbonType = "Tree Ribbon"; + constexpr auto WindowType = "Window Frame"; + constexpr auto WreathType = "Wreath"; }; struct XmlSerializingVisitor : BaseObjectVisitor { @@ -583,7 +583,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { groups->AddAttribute(XmlNodeKeys::mgDefaultCameraAttribute, mg1->GetDefaultCamera()); groups->AddAttribute(XmlNodeKeys::mgxCentreOffsetAttribute, std::to_string(mg1->GetXCentreOffset())); groups->AddAttribute(XmlNodeKeys::mgyCentreOffsetAttribute, std::to_string(mg1->GetYCentreOffset())); - // AddAliases(groups,aliases); + const std::list& aliases = mg1->GetAliases(); + AddAliases(groups,aliases); node->AddChild(groups); } } From 9b8ff5a1cbfd1d89697027b3fd416a3c507594de Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 8 May 2024 12:27:50 -0400 Subject: [PATCH 04/17] XMLSerializer with visitor WIP --- xLights/models/CubeModel.h | 13 +- xLights/models/CustomModel.h | 3 + xLights/models/IciclesModel.cpp | 2 + xLights/models/IciclesModel.h | 5 + xLights/models/ImageModel.h | 3 + xLights/models/MatrixModel.h | 10 +- xLights/models/PolyLineModel.h | 3 + xLights/models/SingleLineModel.cpp | 1 + xLights/models/SingleLineModel.h | 5 + xLights/models/SphereModel.h | 8 +- xLights/models/SpinnerModel.cpp | 1 + xLights/models/SpinnerModel.h | 5 + xLights/models/StarModel.h | 7 +- xLights/models/TreeModel.h | 19 +- xLights/models/WindowFrameModel.cpp | 1 + xLights/models/WindowFrameModel.h | 5 + xLights/models/WreathModel.cpp | 1 + xLights/models/WreathModel.h | 5 + xLights/models/XmlSerializer.h | 571 +++++++++++++++++++++++----- 19 files changed, 532 insertions(+), 136 deletions(-) diff --git a/xLights/models/CubeModel.h b/xLights/models/CubeModel.h index c2df892411..aa389c5aee 100644 --- a/xLights/models/CubeModel.h +++ b/xLights/models/CubeModel.h @@ -33,14 +33,8 @@ class CubeModel : public ModelWithScreenLocation virtual int GetNumStrands() const override { return _strands; }; virtual int MapToNodeIndex(int strand, int node) const override; virtual void ExportAsCustomXModel3D() const override; - virtual bool SupportsExportAsCustom3D() const override - { - return true; - } - virtual bool SupportsExportAsCustom() const override - { - return false; - } + virtual bool SupportsExportAsCustom3D() const override { return true; } + virtual bool SupportsExportAsCustom() const override { return false; } virtual int NodesPerString() const override; virtual std::string ChannelLayoutHtml(OutputManager * outputManager) override; @@ -48,6 +42,9 @@ class CubeModel : public ModelWithScreenLocation virtual void AddTypeProperties(wxPropertyGridInterface* grid, OutputManager* outputManager) override; virtual int OnPropertyGridChange(wxPropertyGridInterface *grid, wxPropertyGridEvent& event) override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: int GetStartIndex() const; int GetStyleIndex() const; diff --git a/xLights/models/CustomModel.h b/xLights/models/CustomModel.h index e36e6d0101..cb167b6c75 100644 --- a/xLights/models/CustomModel.h +++ b/xLights/models/CustomModel.h @@ -70,6 +70,9 @@ class CustomModel : public ModelWithScreenLocation virtual std::list CheckModelSettings() override; virtual int NodesPerString(int string) const override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: virtual void InitModel() override; virtual void SetStringStartChannels(bool zeroBased, int NumberOfStrings, int StartChannel, int ChannelsPerString) override; diff --git a/xLights/models/IciclesModel.cpp b/xLights/models/IciclesModel.cpp index 08157d8c3f..ac9a36a45f 100644 --- a/xLights/models/IciclesModel.cpp +++ b/xLights/models/IciclesModel.cpp @@ -217,3 +217,5 @@ void IciclesModel::AddDimensionProperties(wxPropertyGridInterface* grid) // the height does not make sense for icicles static_cast(screenLocation).AddDimensionProperties(grid, 1.0); } + +void IciclesModel::ExportXlightsModel() {} \ No newline at end of file diff --git a/xLights/models/IciclesModel.h b/xLights/models/IciclesModel.h index 0df011228e..b2c665c871 100644 --- a/xLights/models/IciclesModel.h +++ b/xLights/models/IciclesModel.h @@ -24,6 +24,11 @@ class IciclesModel : public ModelWithScreenLocation virtual bool SupportsWiringView() const override { return true; } virtual std::string GetDimension() const override; virtual void AddDimensionProperties(wxPropertyGridInterface* grid) override; + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: virtual void InitModel() override; diff --git a/xLights/models/ImageModel.h b/xLights/models/ImageModel.h index 07f115762f..1976257278 100644 --- a/xLights/models/ImageModel.h +++ b/xLights/models/ImageModel.h @@ -44,6 +44,9 @@ class ImageModel : public ModelWithScreenLocation virtual bool CleanupFileLocations(xLightsFrame* frame) override; virtual std::list CheckModelSettings() override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: int GetChannelValue(int channel); diff --git a/xLights/models/MatrixModel.h b/xLights/models/MatrixModel.h index db66c7c303..c7da3b56e3 100644 --- a/xLights/models/MatrixModel.h +++ b/xLights/models/MatrixModel.h @@ -30,12 +30,14 @@ class MatrixModel : public ModelWithScreenLocation virtual void AddTypeProperties(wxPropertyGridInterface* grid, OutputManager* outputManager) override; virtual int OnPropertyGridChange(wxPropertyGridInterface *grid, wxPropertyGridEvent& event) override; virtual std::list CheckModelSettings() override; - virtual bool SupportsLowDefinitionRender() const override - { - return SingleNode != true; // we cant do low def on single node matrices - } + // we cant do low def on single node matrices + virtual bool SupportsLowDefinitionRender() const override { return SingleNode != true; } bool isVerticalMatrix() const { return vMatrix; } + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: virtual void AddStyleProperties(wxPropertyGridInterface *grid); diff --git a/xLights/models/PolyLineModel.h b/xLights/models/PolyLineModel.h index 491f3ee8ed..39c524b43a 100644 --- a/xLights/models/PolyLineModel.h +++ b/xLights/models/PolyLineModel.h @@ -50,6 +50,9 @@ class PolyLineModel : public ModelWithScreenLocation virtual int NodesPerString(int string) const override; virtual int MapPhysicalStringToLogicalString(int string) const override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: static std::vector POLYLINE_BUFFER_STYLES; virtual void InitModel() override; diff --git a/xLights/models/SingleLineModel.cpp b/xLights/models/SingleLineModel.cpp index 11ee76da16..c371c9d281 100644 --- a/xLights/models/SingleLineModel.cpp +++ b/xLights/models/SingleLineModel.cpp @@ -261,3 +261,4 @@ int SingleLineModel::OnPropertyGridChange(wxPropertyGridInterface *grid, wxPrope return Model::OnPropertyGridChange(grid, event); } +void SingleLineModel::ExportXlightsModel() {} \ No newline at end of file diff --git a/xLights/models/SingleLineModel.h b/xLights/models/SingleLineModel.h index 0463b3b897..0fd1ea2b09 100644 --- a/xLights/models/SingleLineModel.h +++ b/xLights/models/SingleLineModel.h @@ -30,6 +30,11 @@ class SingleLineModel : public ModelWithScreenLocation virtual int OnPropertyGridChange(wxPropertyGridInterface *grid, wxPropertyGridEvent& event) override; virtual bool SupportsExportAsCustom() const override { return true; } virtual bool SupportsWiringView() const override { return false; } + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; + + virtual bool SupportsVisitors() override { return true;} + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } const Model *GetParent() { return parent; } protected: diff --git a/xLights/models/SphereModel.h b/xLights/models/SphereModel.h index 6eee55204d..246cf1d1b1 100644 --- a/xLights/models/SphereModel.h +++ b/xLights/models/SphereModel.h @@ -26,10 +26,10 @@ class SphereModel : public MatrixModel virtual int NodeRenderOrder() override { return 1; } virtual void ExportAsCustomXModel3D() const override; bool Find3DCustomModelScale(int scale, float minx, float miny, float minz, float w, float h, float d) const; - virtual bool SupportsExportAsCustom3D() const override - { - return true; - } + virtual bool SupportsExportAsCustom3D() const override { return true; } + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: virtual void AddStyleProperties(wxPropertyGridInterface *grid) override; diff --git a/xLights/models/SpinnerModel.cpp b/xLights/models/SpinnerModel.cpp index 3ae1ae5468..1fbcf73d8f 100644 --- a/xLights/models/SpinnerModel.cpp +++ b/xLights/models/SpinnerModel.cpp @@ -578,3 +578,4 @@ int SpinnerModel::NodesPerString() const { } } } +void SpinnerModel::ExportXlightsModel() {} \ No newline at end of file diff --git a/xLights/models/SpinnerModel.h b/xLights/models/SpinnerModel.h index f27b041913..a56d0ce794 100644 --- a/xLights/models/SpinnerModel.h +++ b/xLights/models/SpinnerModel.h @@ -30,6 +30,11 @@ class SpinnerModel : public ModelWithScreenLocation int &BufferWi, int &BufferHi, int stagger) const override; virtual bool SupportsExportAsCustom() const override { return true; } virtual bool SupportsWiringView() const override { return true; } + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: SpinnerModel(const ModelManager &manager); diff --git a/xLights/models/StarModel.h b/xLights/models/StarModel.h index 20de4b7be2..b130ff55fe 100644 --- a/xLights/models/StarModel.h +++ b/xLights/models/StarModel.h @@ -29,9 +29,7 @@ class StarModel : public ModelWithScreenLocation virtual int MapToNodeIndex(int strand, int node) const override; virtual int GetMappedStrand(int strand) const override; - int GetStarSize(int starLayer) const { - return GetLayerSize(starLayer); - } + int GetStarSize(int starLayer) const { return GetLayerSize(starLayer); } virtual int GetNumStrands() const override; virtual bool AllNodesAllocated() const override; @@ -45,6 +43,9 @@ class StarModel : public ModelWithScreenLocation virtual bool ModelSupportsLayerSizes() const override { return true; } virtual void OnLayerSizesChange(bool countChanged) override; + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + protected: static std::vector STAR_BUFFER_STYLES; virtual void InitModel() override; diff --git a/xLights/models/TreeModel.h b/xLights/models/TreeModel.h index f2a9dcbff7..01a0d446bc 100644 --- a/xLights/models/TreeModel.h +++ b/xLights/models/TreeModel.h @@ -22,21 +22,16 @@ class TreeModel : public MatrixModel virtual bool SupportsXlightsModel() override { return true; } virtual bool SupportsExportAsCustom() const override { return true; } virtual void ExportAsCustomXModel3D() const override; - virtual bool SupportsExportAsCustom3D() const override - { - return true; - } - virtual bool SupportsWiringView() const override - { - return true; - } + virtual bool SupportsExportAsCustom3D() const override { return true; } + virtual bool SupportsWiringView() const override { return true; } virtual void ExportXlightsModel() override; virtual void ImportXlightsModel(wxXmlNode* root, xLightsFrame* xlights, float& min_x, float& max_x, float& min_y, float& max_y) override; virtual int NodeRenderOrder() override {return 1;} - virtual bool SupportsLowDefinitionRender() const override - { - return false; // we need to override this as the matrix model can set it to true - } + // we need to override this as the matrix model can set it to true + virtual bool SupportsLowDefinitionRender() const override { return false; } + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: virtual void AddStyleProperties(wxPropertyGridInterface *grid) override; diff --git a/xLights/models/WindowFrameModel.cpp b/xLights/models/WindowFrameModel.cpp index 1a9e16be7d..e661b6f983 100644 --- a/xLights/models/WindowFrameModel.cpp +++ b/xLights/models/WindowFrameModel.cpp @@ -493,3 +493,4 @@ int WindowFrameModel::OnPropertyGridChange(wxPropertyGridInterface *grid, wxProp return Model::OnPropertyGridChange(grid, event); } +void WindowFrameModel::ExportXlightsModel() {} \ No newline at end of file diff --git a/xLights/models/WindowFrameModel.h b/xLights/models/WindowFrameModel.h index f07f42c94c..99cd9c121e 100644 --- a/xLights/models/WindowFrameModel.h +++ b/xLights/models/WindowFrameModel.h @@ -21,6 +21,11 @@ class WindowFrameModel : public ModelWithScreenLocation virtual bool SupportsExportAsCustom() const override { return true; } virtual bool SupportsWiringView() const override { return true; } virtual int NodesPerString() const override; + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: virtual void InitModel() override; diff --git a/xLights/models/WreathModel.cpp b/xLights/models/WreathModel.cpp index ff55665313..ad66d89520 100644 --- a/xLights/models/WreathModel.cpp +++ b/xLights/models/WreathModel.cpp @@ -129,3 +129,4 @@ int WreathModel::OnPropertyGridChange(wxPropertyGridInterface *grid, wxPropertyG return Model::OnPropertyGridChange(grid, event); } +void WreathModel::ExportXlightsModel() {} \ No newline at end of file diff --git a/xLights/models/WreathModel.h b/xLights/models/WreathModel.h index abbe4b985f..478e22dd13 100644 --- a/xLights/models/WreathModel.h +++ b/xLights/models/WreathModel.h @@ -22,6 +22,11 @@ class WreathModel : public ModelWithScreenLocation virtual int OnPropertyGridChange(wxPropertyGridInterface *grid, wxPropertyGridEvent& event) override; virtual bool SupportsExportAsCustom() const override { return true; } virtual bool SupportsWiringView() const override { return true; } + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: virtual void InitModel() override; diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 8759a8402f..f13cbab1ae 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -30,6 +30,7 @@ #include "SphereModel.h" #include "SpinnerModel.h" #include "StarModel.h" +#include "SubModel.h" #include "ThreePointScreenLocation.h" #include "TreeModel.h" #include "WindowFrameModel.h" @@ -529,45 +530,50 @@ struct XmlSerializingVisitor : BaseObjectVisitor { void AddAliases(wxXmlNode* node, const std::list aliases) { wxXmlNode* aliashdr = new wxXmlNode(wxXML_ELEMENT_NODE, "Aliases"); - for (const auto& a : aliases) { - wxXmlNode* alias = new wxXmlNode(wxXML_ELEMENT_NODE, "alias"); - alias->AddAttribute("name", a); - aliashdr->AddChild(alias); + if (aliases.size() > 0) { + for (const auto& a : aliases) { + wxXmlNode* alias = new wxXmlNode(wxXML_ELEMENT_NODE, "alias"); + alias->AddAttribute("name", a); + aliashdr->AddChild(alias); + } + node->AddChild(aliashdr); } - node->AddChild(aliashdr); - } - - void AddSubmodels(wxXmlNode* node, const std::string name, const Model* sm) { - const SubModel* sm0 = dynamic_cast(sm); - wxXmlNode* submodels = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::SubModelNodeName); - submodels->AddAttribute(XmlNodeKeys::SubModelNameAttribute, sm->GetName()); - const std::list& aliases = sm->GetAliases(); - - submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, sm0->GetSubModelLayout()); - submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, sm0->GetSubModelType()); - - const std::string submodelBufferStyle = sm0->GetSubModelBufferStyle(); - if (submodelBufferStyle == "bufferstyle") { - submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, submodelBufferStyle); - } else { - wxArrayString nodeInfo = wxSplit(sm0->GetSubModelNodeRanges(), ','); - for (auto i = 0; i < nodeInfo.size(); i++) { - submodels->AddAttribute("line" + std::to_string(i), nodeInfo[i]); + } + + void AddSubmodels(wxXmlNode* node, const Model* m) { + const std::vector& submodelList = m->GetSubModels(); + + for (Model* s : submodelList) { + wxXmlNode* submodels = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::SubModelNodeName); + const SubModel* submodel = dynamic_cast(s); + if (submodel == nullptr) return; + submodels->AddAttribute(XmlNodeKeys::SubModelNameAttribute, s->GetName()); + submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, submodel->GetSubModelLayout()); + submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, submodel->GetSubModelType()); + const std::string submodelBufferStyle = submodel->GetSubModelBufferStyle(); + if (submodelBufferStyle == "bufferstyle") { + submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, submodelBufferStyle); + } else { + wxArrayString nodeInfo = wxSplit(submodel->GetSubModelNodeRanges(), ','); + for (auto i = 0; i < nodeInfo.size(); i++) { + submodels->AddAttribute("line" + std::to_string(i), nodeInfo[i]); + } } + AddAliases(submodels, s->GetAliases()); + node->AddChild(submodels); } - AddAliases(submodels, aliases); - node->AddChild(submodels); } - void AddGroups(wxXmlNode* node, const std::string name, const Model* m) { + void AddGroups(wxXmlNode* node, const Model* m) { const ModelManager& mgr = m->GetModelManager(); std::vector mg = mgr.GetModelGroups(m); for (const Model* g : mg) { const ModelGroup* mg1 = dynamic_cast(g); + if (mg1 == nullptr) return; wxXmlNode* groups = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::GroupNodeName); groups->AddAttribute(XmlNodeKeys::mgNameAttribute, g->GetName()); - groups->AddAttribute(XmlNodeKeys::mgModelsAttribute, name); + groups->AddAttribute(XmlNodeKeys::mgModelsAttribute, m->GetName()); groups->AddAttribute(XmlNodeKeys::mgLayoutGroupAttribute, g->GetLayoutGroup()); groups->AddAttribute(XmlNodeKeys::mgSelectedAttribute, std::to_string(mg1->IsSelected())); groups->AddAttribute(XmlNodeKeys::mgLayoutAttribute, mg1->GetLayout()); @@ -589,105 +595,247 @@ struct XmlSerializingVisitor : BaseObjectVisitor { } } - void Visit(const ArchesModel& arch) override { - wxXmlNode* archNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); - - const std::vector& submodels = arch.GetSubModels(); - const std::list& aliases = arch.GetAliases(); - const std::string name = arch.GetName(); - - const Model* m = dynamic_cast(&arch); - - AddBaseObjectAttributes(arch, archNode); - AddCommonModelAttributes(arch, archNode); - AddModelScreenLocationAttributes(arch, archNode); - AddThreePointScreenLocationAttributes(arch, archNode); - archNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, std::to_string(arch.GetZigZag())); - archNode->AddAttribute(XmlNodeKeys::HollowAttribute, std::to_string(arch.GetHollow())); - archNode->AddAttribute(XmlNodeKeys::GapAttribute, std::to_string(arch.GetGap())); - archNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(arch.GetLayerSizes())); - AddAliases(archNode, aliases); - for (Model* submodel : submodels) { - Model* sm = arch.GetSubModel(submodel->GetName()); - AddSubmodels(archNode, name, sm); - } - AddGroups(archNode, name, m); - parentNode->AddChild(archNode); + void Visit(const ArchesModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, std::to_string(model.GetZigZag())); + xmlNode->AddAttribute(XmlNodeKeys::HollowAttribute, std::to_string(model.GetHollow())); + xmlNode->AddAttribute(XmlNodeKeys::GapAttribute, std::to_string(model.GetGap())); + xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const CandyCaneModel& cc) override { - wxXmlNode* ccNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); - - const std::vector& submodels = cc.GetSubModels(); - const std::list& aliases = cc.GetAliases(); - const std::string name = cc.GetName(); - - const Model* m = dynamic_cast(&cc); - - AddBaseObjectAttributes(cc, ccNode); - AddCommonModelAttributes(cc, ccNode); - AddModelScreenLocationAttributes(cc, ccNode); - AddThreePointScreenLocationAttributes(cc, ccNode); - AddAliases(ccNode, aliases); - for (Model* submodel : submodels) { - Model* sm = cc.GetSubModel(submodel->GetName()); - AddSubmodels(ccNode, name, sm); - } - AddGroups(ccNode, name, m); - parentNode->AddChild(ccNode); + void Visit(const CandyCaneModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const CircleModel& circle) override { - wxXmlNode* circleNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); - - const std::vector& submodels = circle.GetSubModels(); - const std::list& aliases = circle.GetAliases(); - const std::string name = circle.GetName(); - - const Model* m = dynamic_cast(&circle); - - AddBaseObjectAttributes(circle, circleNode); - AddCommonModelAttributes(circle, circleNode); - AddModelScreenLocationAttributes(circle, circleNode); - // AddThreePointScreenLocationAttributes(circle, circleNode); //export crashes, most likely an attribute that doesn't exist - need to look into - AddAliases(circleNode, aliases); - for (Model* submodel : submodels) { - Model* sm = circle.GetSubModel(submodel->GetName()); - AddSubmodels(circleNode, name, sm); - } - AddGroups(circleNode, name, m); - parentNode->AddChild(circleNode); + void Visit(const CircleModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const ChannelBlockModel& channelblock) override { + void Visit(const ChannelBlockModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const CubeModel& cube) override { + + void Visit(const CubeModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const CustomModel& custom) override { + + void Visit(const CustomModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const IciclesModel& icicles) override { + void Visit(const IciclesModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const ImageModel& image) override { + + void Visit(const ImageModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const MatrixModel& matricx) override { + + void Visit(const MatrixModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const SingleLineModel& singleline) override { + + void Visit(const SingleLineModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const PolyLineModel& polyline) override { + + void Visit(const PolyLineModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const SphereModel& sphere) override { + + void Visit(const SphereModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const SpinnerModel& spinner) override { + + void Visit(const SpinnerModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const StarModel& star) override { + + void Visit(const StarModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const TreeModel& tree) override { + + void Visit(const TreeModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } + // void Visit(const TreeModel &treeflat) override {} // void Visit(const TreeModel &treeribbon) override {} - void Visit(const WindowFrameModel& window) override { + + void Visit(const WindowFrameModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } - void Visit(const WreathModel& wreath) override { + + void Visit(const WreathModel& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + //AddThreePointScreenLocationAttributes(model, xmlNode); + AddAliases(xmlNode, model.GetAliases()); + const Model* m = dynamic_cast(&model); + if (m == nullptr) return; + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); } void Visit(const DmxMovingHeadAdv& moving_head) override { @@ -704,6 +852,11 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddMeshAttributes(reinterpret_cast(moving_head.GetBaseMesh()), mhNode); AddMeshAttributes(reinterpret_cast(moving_head.GetYokeMesh()), mhNode); AddMeshAttributes(reinterpret_cast(moving_head.GetHeadMesh()), mhNode); + const Model* m = dynamic_cast(&moving_head); + if (m == nullptr) + return; + AddSubmodels(mhNode, m); + AddGroups(mhNode, m); parentNode->AddChild(mhNode); } }; @@ -716,10 +869,42 @@ struct XmlDeserializingObjectFactory { return DeserializeArches(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::CandyCaneType) { return DeserializeCandyCane(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::ChannelBlockType) { + return DeserializeChannelBlock(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::CircleType) { return DeserializeCircle(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::CubeType) { + return DeserializeCube(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::CustomType) { + return DeserializeCustom(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::DmxMovingHeadAdvType) { return DeserializeDmxMovingHeadAdv(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::IciclesType) { + return DeserializeIcicles(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::ImageType) { + return DeserializeImage(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::MatrixType) { + return DeserializeMatrix(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::SingleLineType) { + return DeserializeSingleLine(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::PolyLineType) { + return DeserializePolyLine(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::SphereType) { + return DeserializeSphere(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::SpinnerType) { + return DeserializeSpinner(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::StarType) { + return DeserializeStar(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::Tree360Type) { + return DeserializeTree360(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::TreeFlatType) { + return DeserializeTreeFlat(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::TreeRibbonType) { + return DeserializeTreeRibbon(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::WindowType) { + return DeserializeWindow(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::WreathType) { + return DeserializeWreath(new wxXmlNode(*node), xlights); } throw std::runtime_error("Unknown object type: " + type); @@ -748,6 +933,17 @@ struct XmlDeserializingObjectFactory { return model; } + Model* DeserializeChannelBlock(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new ChannelBlockModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + Model* DeserializeCircle(wxXmlNode* node, xLightsFrame* xlights) { Model* model; model = new CircleModel(node, xlights->AllModels, false); @@ -759,6 +955,28 @@ struct XmlDeserializingObjectFactory { return model; } + Model* DeserializeCube(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new CubeModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeCustom(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new CustomModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + Model* DeserializeDmxMovingHeadAdv(wxXmlNode* node, xLightsFrame* xlights) { Model* model; model = new DmxMovingHeadAdv(node, xlights->AllModels, false); @@ -776,6 +994,149 @@ struct XmlDeserializingObjectFactory { return model; } + + Model* DeserializeIcicles(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new IciclesModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeImage(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new ImageModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeMatrix(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new MatrixModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeSingleLine(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new SingleLineModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializePolyLine(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new PolyLineModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeSphere(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new SphereModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeSpinner(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new SpinnerModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeStar(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new StarModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeTree360(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new TreeModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeTreeFlat(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new TreeModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeTreeRibbon(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new TreeModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeWindow(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WindowFrameModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeWreath(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } }; struct XmlSerializer { From 1a3ce6be56b9faf8d5deac42e1baa616fafbe8b0 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 8 May 2024 15:16:30 -0400 Subject: [PATCH 05/17] XMLSerializer with visitor WIPXMLSerializer with visitor WIP --- xLights/models/ArchesModel.h | 1 + xLights/models/CandyCaneModel.h | 4 ++++ xLights/models/Model.h | 2 ++ xLights/models/XmlSerializer.h | 33 +++++++++++++++++++++++++++------ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/xLights/models/ArchesModel.h b/xLights/models/ArchesModel.h index c0d07c70fc..e123084a79 100644 --- a/xLights/models/ArchesModel.h +++ b/xLights/models/ArchesModel.h @@ -41,6 +41,7 @@ class ArchesModel : public ModelWithScreenLocation bool GetZigZag() const { return zigzag; } int GetHollow() const { return _hollow; } int GetGap() const { return _gap; } + int GetArc() const { return arc; } virtual bool SupportsVisitors() override {return true;} void Accept(BaseObjectVisitor &visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/CandyCaneModel.h b/xLights/models/CandyCaneModel.h index 5078e07618..e96e028719 100644 --- a/xLights/models/CandyCaneModel.h +++ b/xLights/models/CandyCaneModel.h @@ -36,6 +36,10 @@ class CandyCaneModel : public ModelWithScreenLocation virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + bool IsReverse() const { return _reverse; } + bool IsSticks() const { return _sticks; } + bool HasAlternateNodes() const { return _alternateNodes; } + float GetCandyCaneHeight() const { return _caneheight; } protected: virtual void InitModel() override; diff --git a/xLights/models/Model.h b/xLights/models/Model.h index 0332b80afc..a1d88c3296 100644 --- a/xLights/models/Model.h +++ b/xLights/models/Model.h @@ -143,6 +143,8 @@ class Model : public BaseObject long GetParm2() const { return parm2; } long GetParm3() const { return parm3; } int GetTransparency() const { return transparency; } + int GetBlackTransparency() const { return blackTransparency; } + std::string GetDescription() const { return description; } const std::string GetNodeNames() const { return _nodeNamesString; } const std::string GetStrandNames() const { return _strandNamesString; } diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index f13cbab1ae..efe2c2c469 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -73,6 +73,8 @@ namespace XmlNodeKeys { constexpr auto FromBaaseAttribute = "FromBase"; constexpr auto DescriptionAttribute = "Description"; constexpr auto CustomStringsAttribute = "String"; + constexpr auto TagColourAttribute = "TagColour"; + // Common SubModel Attributes constexpr auto SubModelNodeName = "subModel"; @@ -185,6 +187,11 @@ namespace XmlNodeKeys { constexpr auto StartNullAttribute = "startNull"; constexpr auto EndNullAttribute = "endNull"; + // Shared (by some) Attributes + constexpr auto ArcAttribute = "Arc"; + constexpr auto arcAttribute = "arc"; //Arches is lowercase - maybe should be fixed + constexpr auto AlternateNodesAttribute = "AlternateNodes"; + // Arch Attributes constexpr auto ZigZagAttribute = "ZigZag"; constexpr auto HollowAttribute = "Hollow"; @@ -197,6 +204,11 @@ namespace XmlNodeKeys { // Arch, CandyCane, Icicles, Single Line Models + // Candy Canes + constexpr auto CCHeightAttribute = "CandyCaneHeight"; + constexpr auto CCReverseAttribute = "CandyCaneReverse"; + constexpr auto CCSticksAttribute = "CandyCaneSticks"; + // Channel Block Model constexpr auto ChannelPropertiesCC1Attribute = "ChannelProperties.ChannelColor1"; constexpr auto ChannelPropertiesCC2Attribute = "ChannelProperties.ChannelColor2"; @@ -252,7 +264,6 @@ namespace XmlNodeKeys { constexpr auto CornerAttribute = "Corner"; // needs fix Corner1, Corner2, Corner3 // Spinner Model - constexpr auto ArcAttribute = "Arc"; constexpr auto StringAttribute = "String"; constexpr auto AlternateAttribute = "Alternate"; constexpr auto StartAttribute = "Start"; @@ -260,7 +271,6 @@ namespace XmlNodeKeys { // Star Model constexpr auto StarStartLocationAttribute = "StarStartLocation"; constexpr auto LayerSizesAttribute = "LayerSizes"; - constexpr auto TagColourAttribute = "TagColour"; // Tree Model constexpr auto TreeBottomTopRatioAttribute = "TreeBottomTopRatio"; @@ -401,6 +411,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { node->AddAttribute(XmlNodeKeys::PixelSizeAttribute, std::to_string(model.GetPixelSize())); node->AddAttribute(XmlNodeKeys::StringTypeAttribute, model.GetStringType()); node->AddAttribute(XmlNodeKeys::TransparencyAttribute, std::to_string(model.GetTransparency())); + node->AddAttribute(XmlNodeKeys::BTransparencyAttribute, std::to_string(model.GetBlackTransparency())); + node->AddAttribute(XmlNodeKeys::DescriptionAttribute, model.GetDescription()); + node->AddAttribute(XmlNodeKeys::TagColourAttribute, model.GetTagColour().GetAsString(wxC2S_HTML_SYNTAX)); node->AddAttribute(XmlNodeKeys::StartChannelAttribute, model.GetModelStartChannel()); node->AddAttribute(XmlNodeKeys::NodeNamesAttribute, model.GetNodeNames()); node->AddAttribute(XmlNodeKeys::StrandNamesAttribute, model.GetStrandNames()); @@ -550,9 +563,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { submodels->AddAttribute(XmlNodeKeys::SubModelNameAttribute, s->GetName()); submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, submodel->GetSubModelLayout()); submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, submodel->GetSubModelType()); - const std::string submodelBufferStyle = submodel->GetSubModelBufferStyle(); - if (submodelBufferStyle == "bufferstyle") { - submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, submodelBufferStyle); + submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, submodel->GetSubModelBufferStyle()); + const std::string submodelType = submodel->GetSubModelType(); + if (submodelType == "subbuffer") { + submodels->AddAttribute(XmlNodeKeys::SubBufferStyleAttribute, submodel->GetSubModelNodeRanges()); } else { wxArrayString nodeInfo = wxSplit(submodel->GetSubModelNodeRanges(), ','); for (auto i = 0; i < nodeInfo.size(); i++) { @@ -595,15 +609,18 @@ struct XmlSerializingVisitor : BaseObjectVisitor { } } + //xmlNode->AddAttribute(XmlNodeKeys::#, std::to_string(#())); + void Visit(const ArchesModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); AddThreePointScreenLocationAttributes(model, xmlNode); - xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, std::to_string(model.GetZigZag())); + xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, model.GetZigZag() ? "true": "false"); xmlNode->AddAttribute(XmlNodeKeys::HollowAttribute, std::to_string(model.GetHollow())); xmlNode->AddAttribute(XmlNodeKeys::GapAttribute, std::to_string(model.GetGap())); + xmlNode->AddAttribute(XmlNodeKeys::arcAttribute, std::to_string(model.GetArc())); xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); @@ -618,6 +635,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::CCHeightAttribute, std::to_string(model.GetCandyCaneHeight())); + xmlNode->AddAttribute(XmlNodeKeys::CCReverseAttribute, model.IsReverse() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::CCSticksAttribute, model.IsSticks() ? "true": "false"); + xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; From 2c2c50347318a85efd84f2db70ee83038cdf5ae6 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 9 May 2024 11:31:47 -0400 Subject: [PATCH 06/17] XMLSerializer with visitor WIP --- xLights/models/ChannelBlockModel.cpp | 10 ++ xLights/models/ChannelBlockModel.h | 6 + xLights/models/CircleModel.h | 1 + xLights/models/CubeModel.cpp | 16 +++ xLights/models/CubeModel.h | 5 + xLights/models/IciclesModel.cpp | 1 + xLights/models/IciclesModel.h | 3 + xLights/models/ImageModel.cpp | 2 + xLights/models/ImageModel.h | 2 + xLights/models/MatrixModel.h | 3 + xLights/models/PolyLineModel.cpp | 27 ++++ xLights/models/PolyLineModel.h | 13 ++ xLights/models/SphereModel.h | 4 + xLights/models/SpinnerModel.h | 5 + xLights/models/StarModel.h | 3 + xLights/models/TreeModel.cpp | 1 + xLights/models/TreeModel.h | 8 ++ xLights/models/WindowFrameModel.h | 1 + xLights/models/XmlSerializer.h | 199 ++++++++++++++++----------- 19 files changed, 227 insertions(+), 83 deletions(-) diff --git a/xLights/models/ChannelBlockModel.cpp b/xLights/models/ChannelBlockModel.cpp index 3e5e91dbd8..1551014631 100644 --- a/xLights/models/ChannelBlockModel.cpp +++ b/xLights/models/ChannelBlockModel.cpp @@ -243,3 +243,13 @@ int ChannelBlockModel::GetNumStrands() const { int ChannelBlockModel::CalcCannelsPerString() { return GetNodeChannelCount(StringType); } +void ChannelBlockModel::ExportXlightsModel() {} + +std::vector ChannelBlockModel::GetChannelProperies() const { + std::vector channelPropColour; + for (auto i = 0; i < GetNumStrands(); i++) { + wxString nm = ChanColorAttrName(i); + channelPropColour.push_back(ModelXml->GetAttribute("ChannelProperties." + nm).ToStdString()); + } + return channelPropColour; +} \ No newline at end of file diff --git a/xLights/models/ChannelBlockModel.h b/xLights/models/ChannelBlockModel.h index 31a4691756..0aa810e243 100644 --- a/xLights/models/ChannelBlockModel.h +++ b/xLights/models/ChannelBlockModel.h @@ -32,6 +32,12 @@ class ChannelBlockModel : public ModelWithScreenLocation virtual int GetNumPhysicalStrings() const override { return 1; } virtual bool SupportsExportAsCustom() const override { return false; } virtual bool SupportsWiringView() const override { return false; } + virtual bool SupportsXlightsModel() override { return true; } + virtual void ExportXlightsModel() override; + std::vector GetChannelProperies() const; + + virtual bool SupportsVisitors() override { return true; } + void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } protected: virtual void InitModel() override; diff --git a/xLights/models/CircleModel.h b/xLights/models/CircleModel.h index d9a5620a5d..a6c7c08869 100644 --- a/xLights/models/CircleModel.h +++ b/xLights/models/CircleModel.h @@ -37,6 +37,7 @@ class CircleModel : public ModelWithScreenLocation virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + bool IsInsideOut() const { return insideOut; } protected: virtual void InitModel() override; diff --git a/xLights/models/CubeModel.cpp b/xLights/models/CubeModel.cpp index 662cc40a1f..7789553ed3 100644 --- a/xLights/models/CubeModel.cpp +++ b/xLights/models/CubeModel.cpp @@ -384,6 +384,22 @@ std::string CubeModel::GetStartLocation() const return ModelXml->GetAttribute("Start", "") + " " + ModelXml->GetAttribute("Style", ""); } +std::string CubeModel::GetStrandStart() const { + return ModelXml->GetAttribute("Start", ""); +} + +std::string CubeModel::GetStrandStyle() const { + return ModelXml->GetAttribute("Style", ""); +} + +std::string CubeModel::GetStrandPerLine() const { + return ModelXml->GetAttribute("StrandPerLine", ""); +} + +std::string CubeModel::GetStrandPerLayer() const { + return ModelXml->GetAttribute("StrandPerLayer", ""); +} + std::vector> CubeModel::BuildCube() const { static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); diff --git a/xLights/models/CubeModel.h b/xLights/models/CubeModel.h index aa389c5aee..e0f6d99e8b 100644 --- a/xLights/models/CubeModel.h +++ b/xLights/models/CubeModel.h @@ -45,6 +45,11 @@ class CubeModel : public ModelWithScreenLocation virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + std::string GetStrandStyle() const; + std::string GetStrandPerLine() const; + std::string GetStrandPerLayer() const; + std::string GetStrandStart() const; + protected: int GetStartIndex() const; int GetStyleIndex() const; diff --git a/xLights/models/IciclesModel.cpp b/xLights/models/IciclesModel.cpp index ac9a36a45f..1c9cd41401 100644 --- a/xLights/models/IciclesModel.cpp +++ b/xLights/models/IciclesModel.cpp @@ -30,6 +30,7 @@ void IciclesModel::InitModel() { wxString dropPattern = GetModelXml()->GetAttribute("DropPattern", "3,4,5,4"); _alternateNodes = (ModelXml->GetAttribute("AlternateNodes", "false") == "true"); + _dropPattern = ModelXml->GetAttribute("DropPattern", ""); wxArrayString pat = wxSplit(dropPattern, ','); int numStrings = parm1; int lightsPerString = parm2; diff --git a/xLights/models/IciclesModel.h b/xLights/models/IciclesModel.h index b2c665c871..af36dc6a61 100644 --- a/xLights/models/IciclesModel.h +++ b/xLights/models/IciclesModel.h @@ -26,6 +26,8 @@ class IciclesModel : public ModelWithScreenLocation virtual void AddDimensionProperties(wxPropertyGridInterface* grid) override; virtual bool SupportsXlightsModel() override { return true; } virtual void ExportXlightsModel() override; + bool HasAlternateNodes() const { return _alternateNodes; } + std::string GetDropPattern() const { return _dropPattern; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } @@ -36,4 +38,5 @@ class IciclesModel : public ModelWithScreenLocation private: void SetIciclesCoord(); bool _alternateNodes = false; + std::string _dropPattern = ""; }; diff --git a/xLights/models/ImageModel.cpp b/xLights/models/ImageModel.cpp index b4d41a5c69..a69bf0fe4e 100644 --- a/xLights/models/ImageModel.cpp +++ b/xLights/models/ImageModel.cpp @@ -500,3 +500,5 @@ int ImageModel::GetChannelValue(int channel) Nodes[channel]->GetColor(c); return std::max(c.red, std::max(c.green, c.blue)); } + +void ImageModel::ExportXlightsModel() {} \ No newline at end of file diff --git a/xLights/models/ImageModel.h b/xLights/models/ImageModel.h index 1976257278..8f669820bc 100644 --- a/xLights/models/ImageModel.h +++ b/xLights/models/ImageModel.h @@ -43,6 +43,8 @@ class ImageModel : public ModelWithScreenLocation virtual std::list GetFileReferences() override; virtual bool CleanupFileLocations(xLightsFrame* frame) override; virtual std::list CheckModelSettings() override; + virtual void ExportXlightsModel() override; + std::string GetImageFile() const { return _imageFile; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/MatrixModel.h b/xLights/models/MatrixModel.h index c7da3b56e3..98632b0a8f 100644 --- a/xLights/models/MatrixModel.h +++ b/xLights/models/MatrixModel.h @@ -37,6 +37,9 @@ class MatrixModel : public ModelWithScreenLocation virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + bool HasAlternateNodes() const { return _alternateNodes; } + bool IsNoZigZag() const { return _noZig; } + int GetLowDefFactor() const { return _lowDefFactor; } protected: virtual void AddStyleProperties(wxPropertyGridInterface *grid); diff --git a/xLights/models/PolyLineModel.cpp b/xLights/models/PolyLineModel.cpp index 2504920584..3eb9f26abb 100644 --- a/xLights/models/PolyLineModel.cpp +++ b/xLights/models/PolyLineModel.cpp @@ -1667,6 +1667,33 @@ void PolyLineModel::NormalizePointData() ModelXml->AddAttribute("cPointData", cpoint_data); } +std::string PolyLineModel::GetPointData() const { + return ModelXml->GetAttribute("PointData", ""); +} + +std::string PolyLineModel::GetcPointData() const { + return ModelXml->GetAttribute("cPointData", ""); +} + +std::string PolyLineModel::GetNumPoints() const { + return ModelXml->GetAttribute("NumPoints", ""); +} + +std::string PolyLineModel::GetDropPattern() const { + return ModelXml->GetAttribute("DropPattern", "1"); +} + +std::vector PolyLineModel::GetCorners() const { + std::vector c; + wxString pts = ModelXml->GetAttribute("NumPoints"); + int count = wxAtoi(pts); + for (int x = 0; x < count; x++) { + wxString corner = ModelXml->GetAttribute(CornerAttrName(x), "Neither"); + c.push_back(corner); + } + return c; +} + // This is required because users dont need to have their start nodes for each string in ascending // order ... this helps us name the strings correctly int PolyLineModel::MapPhysicalStringToLogicalString(int string) const diff --git a/xLights/models/PolyLineModel.h b/xLights/models/PolyLineModel.h index 39c524b43a..fb329a4a0e 100644 --- a/xLights/models/PolyLineModel.h +++ b/xLights/models/PolyLineModel.h @@ -49,6 +49,19 @@ class PolyLineModel : public ModelWithScreenLocation virtual bool IsNodeFirst(int node) const override; virtual int NodesPerString(int string) const override; virtual int MapPhysicalStringToLogicalString(int string) const override; + bool HasAlternateNodes() const { return _alternateNodes; } + bool HasIndivSegs() const { return hasIndivSeg; } + int GetDropPoints() const { return numDropPoints; } + int GetNumSegments() const { return num_segments; } + std::vector GetSegmentsSizes() const { return polyLineSegDropSizes;} + std::vector GetCorners() const; + std::string GetPointData() const; + std::string GetcPointData() const; + std::string GetNumPoints() const; + std::string GetDropPattern() const; + + bool AreSegsExpanded() const { return segs_collapsed; } + float GetHeight() const { return height; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/SphereModel.h b/xLights/models/SphereModel.h index 246cf1d1b1..5132c90fd5 100644 --- a/xLights/models/SphereModel.h +++ b/xLights/models/SphereModel.h @@ -27,6 +27,10 @@ class SphereModel : public MatrixModel virtual void ExportAsCustomXModel3D() const override; bool Find3DCustomModelScale(int scale, float minx, float miny, float minz, float w, float h, float d) const; virtual bool SupportsExportAsCustom3D() const override { return true; } + int GetStartLatitude() const { return _startLatitude; } + int GetEndLatitude() const { return _endLatitude; } + int GetSphereDegrees() const { return _sphereDegrees; } + int GetLowDefFactor() const { return _lowDefFactor; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/SpinnerModel.h b/xLights/models/SpinnerModel.h index a56d0ce794..688cf3a1d2 100644 --- a/xLights/models/SpinnerModel.h +++ b/xLights/models/SpinnerModel.h @@ -32,6 +32,11 @@ class SpinnerModel : public ModelWithScreenLocation virtual bool SupportsWiringView() const override { return true; } virtual bool SupportsXlightsModel() override { return true; } virtual void ExportXlightsModel() override; + int GetHollowPercent() const { return hollow; } + int GetArcAngle () const { return arc; } + bool HasZigZag() const { return zigzag; } + bool HasAlternateNodes() const { return alternate; } + int GetStartAngle() const { return startangle; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/StarModel.h b/xLights/models/StarModel.h index b130ff55fe..99410b644d 100644 --- a/xLights/models/StarModel.h +++ b/xLights/models/StarModel.h @@ -42,6 +42,9 @@ class StarModel : public ModelWithScreenLocation virtual bool ModelSupportsLayerSizes() const override { return true; } virtual void OnLayerSizesChange(bool countChanged) override; + float GetStarRatio() const { return starRatio; } + int GetInnerPercent() const { return innerPercent; } + std::string GetStartLocation() const { return _starStartLocation; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/TreeModel.cpp b/xLights/models/TreeModel.cpp index 7c5e775dcf..9cc9a39026 100644 --- a/xLights/models/TreeModel.cpp +++ b/xLights/models/TreeModel.cpp @@ -45,6 +45,7 @@ static wxPGChoices TREE_DIRECTIONS(wxArrayString(2, TREE_DIRECTION_VALUES)); void TreeModel::InitModel() { _alternateNodes = (ModelXml->GetAttribute("AlternateNodes", "false") == "true"); _noZig = (ModelXml->GetAttribute("NoZig", "false") == "true"); + _displayAs = (ModelXml->GetAttribute("DisplayAs")); bool isHMatrix = (ModelXml->GetAttribute("StrandDir", TREE_DIRECTION_VALUES[1]) == TREE_DIRECTION_VALUES[0]); wxStringTokenizer tkz(DisplayAs, " "); wxString token = tkz.GetNextToken(); diff --git a/xLights/models/TreeModel.h b/xLights/models/TreeModel.h index 01a0d446bc..18ae3819f0 100644 --- a/xLights/models/TreeModel.h +++ b/xLights/models/TreeModel.h @@ -29,6 +29,13 @@ class TreeModel : public MatrixModel virtual int NodeRenderOrder() override {return 1;} // we need to override this as the matrix model can set it to true virtual bool SupportsLowDefinitionRender() const override { return false; } + int GetTreeType() const { return treeType; } + float GetTreeDegrees() const { return degrees; } + float GetTreeRotation() const { return rotation; } + float GetSpiralRotations() const { return spiralRotations; } + float GetBottomTopRatio() const { return botTopRatio; } + float GetTreePerspective() const { return perspective; } + std::string GetTreeDescription() const { return _displayAs; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } @@ -43,5 +50,6 @@ class TreeModel : public MatrixModel float spiralRotations; float botTopRatio; float perspective; + std::string _displayAs; void SetTreeCoord(long degrees); }; diff --git a/xLights/models/WindowFrameModel.h b/xLights/models/WindowFrameModel.h index 99cd9c121e..f5440e7c83 100644 --- a/xLights/models/WindowFrameModel.h +++ b/xLights/models/WindowFrameModel.h @@ -23,6 +23,7 @@ class WindowFrameModel : public ModelWithScreenLocation virtual int NodesPerString() const override; virtual bool SupportsXlightsModel() override { return true; } virtual void ExportXlightsModel() override; + int GetRotation() const { return rotation; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index efe2c2c469..b2fbbd645d 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -1,4 +1,5 @@ #pragma once +#pragma once /*************************************************************** * This source files comes from the xLights project @@ -187,55 +188,41 @@ namespace XmlNodeKeys { constexpr auto StartNullAttribute = "startNull"; constexpr auto EndNullAttribute = "endNull"; + // Mesh Attributes + constexpr auto ObjFileAttribute = "ObjFile"; + constexpr auto MeshOnlyAttribute = "MeshOnly"; + constexpr auto BrightnessAttribute = "Brightness"; + // Shared (by some) Attributes - constexpr auto ArcAttribute = "Arc"; - constexpr auto arcAttribute = "arc"; //Arches is lowercase - maybe should be fixed + constexpr auto ArcAttribute = "Arc"; + constexpr auto arcAttribute = "arc"; //Arches is lowercase - maybe should be fixed constexpr auto AlternateNodesAttribute = "AlternateNodes"; + constexpr auto LayerSizesAttribute = "LayerSizes"; + constexpr auto ZigZagAttribute = "ZigZag"; // Arch Attributes - constexpr auto ZigZagAttribute = "ZigZag"; constexpr auto HollowAttribute = "Hollow"; constexpr auto GapAttribute = "Gap"; - // Mesh Attributes - constexpr auto ObjFileAttribute = "ObjFile"; - constexpr auto MeshOnlyAttribute = "MeshOnly"; - constexpr auto BrightnessAttribute = "Brightness"; - - // Arch, CandyCane, Icicles, Single Line Models - // Candy Canes constexpr auto CCHeightAttribute = "CandyCaneHeight"; constexpr auto CCReverseAttribute = "CandyCaneReverse"; constexpr auto CCSticksAttribute = "CandyCaneSticks"; // Channel Block Model - constexpr auto ChannelPropertiesCC1Attribute = "ChannelProperties.ChannelColor1"; - constexpr auto ChannelPropertiesCC2Attribute = "ChannelProperties.ChannelColor2"; - constexpr auto ChannelPropertiesCC3Attribute = "ChannelProperties.ChannelColor3"; - constexpr auto ChannelPropertiesCC4Attribute = "ChannelProperties.ChannelColor4"; - constexpr auto ChannelPropertiesCC5Attribute = "ChannelProperties.ChannelColor5"; - constexpr auto ChannelPropertiesCC6Attribute = "ChannelProperties.ChannelColor6"; - constexpr auto ChannelPropertiesCC7Attribute = "ChannelProperties.ChannelColor7"; - constexpr auto ChannelPropertiesCC8Attribute = "ChannelProperties.ChannelColor8"; - constexpr auto ChannelPropertiesCC9Attribute = "ChannelProperties.ChannelColor9"; - constexpr auto ChannelPropertiesCC10Attribute = "ChannelProperties.ChannelColor10"; - constexpr auto ChannelPropertiesCC11Attribute = "ChannelProperties.ChannelColor11"; - constexpr auto ChannelPropertiesCC12Attribute = "ChannelProperties.ChannelColor12"; - constexpr auto ChannelPropertiesCC13Attribute = "ChannelProperties.ChannelColor13"; - constexpr auto ChannelPropertiesCC14Attribute = "ChannelProperties.ChannelColor14"; - constexpr auto ChannelPropertiesCC15Attribute = "ChannelProperties.ChannelColor15"; - constexpr auto ChannelPropertiesCC16Attribute = "ChannelProperties.ChannelColor16"; + // Since this is dynamic it all gets done by the visitor // Circle Model constexpr auto InsideOutAttribute = "InsideOut"; // Cube - constexpr auto StyleAttribute = "Style"; - constexpr auto StrandPerLineAttribute = "SrtrandPerLine"; + constexpr auto StyleAttribute = "Style"; + constexpr auto CubeStartAttribute = "Start"; + constexpr auto StrandPerLineAttribute = "StrandPerLine"; + constexpr auto StrandPerLayerAttribute = "StrandPerLayer"; // Custom Model - constexpr auto CustomModel = "Custom"; + constexpr auto CustomModelAttribute = "CustomModel"; constexpr auto CMBrightnessAttribute = "Brightness"; constexpr auto StrandsAttribute = "Strands"; constexpr auto NodesAttribute = "Nodes"; @@ -243,8 +230,10 @@ namespace XmlNodeKeys { constexpr auto PixelTypeAttribute = "PixelType"; constexpr auto PixelSpacingAttribute = "PixelSpacing"; constexpr auto PixelAttribute = "Pixel"; - constexpr auto BkgLightnessAttribute = "BkgLightness"; + constexpr auto BkgLightnessAttribute = "CustomBkgLightness"; + constexpr auto BkgImageAttribute = "CustomBkgImage"; constexpr auto BkgAttribute = "Bkg"; + constexpr auto CMDepthAttribute = "Depth"; // Image Model constexpr auto ImageAttribute = "Image"; @@ -254,30 +243,41 @@ namespace XmlNodeKeys { // Icicles Model constexpr auto DropPatternAttribute = "DropPattern"; + // Matrix + constexpr auto LowDefinitionAttribute = "LowDefinition"; + constexpr auto NoZigZagAttribute = "NoZig"; + // Poly Line Model - constexpr auto NumPointsAttribute = "NumPoints"; - constexpr auto PointDataAttribute = "PointData"; - constexpr auto cPointDataAttribute = "cPointData"; - constexpr auto IndivegAttribute = "Indiveg"; - constexpr auto SegExpandedAttribute = "SegExpanded"; - constexpr auto SegAttribute = "Seg"; // needs fix Seg1, Seg2, Seg3 - constexpr auto CornerAttribute = "Corner"; // needs fix Corner1, Corner2, Corner3 + constexpr auto NumPointsAttribute = "NumPoints"; + constexpr auto PointDataAttribute = "PointData"; + constexpr auto cPointDataAttribute = "cPointData"; + constexpr auto IndivSegAttribute = "IndivSegs"; + constexpr auto SegsExpandedAttribute = "SegsExpanded"; + constexpr auto ModelHeightAttribute = "ModelHeight"; + + // Sphere + constexpr auto DegreesAttribute = "Degrees"; + constexpr auto StartLatAttribute = "StartLatitude"; + constexpr auto EndLatAttribute = "EndLatitude"; // Spinner Model - constexpr auto StringAttribute = "String"; - constexpr auto AlternateAttribute = "Alternate"; - constexpr auto StartAttribute = "Start"; + constexpr auto StartAngleAttribute = "StartAngle"; + constexpr auto HallowAttribute = "Hollow"; + constexpr auto ArcAngleAttribute = "Arc"; + constexpr auto AlternateAttribute = "Alternate"; // Star Model - constexpr auto StarStartLocationAttribute = "StarStartLocation"; - constexpr auto LayerSizesAttribute = "LayerSizes"; + constexpr auto StarStartLocationAttribute = "StarStartLocation"; + constexpr auto StarRatioAttribute = "starRatio"; + constexpr auto StarCenterPercentAttribute = "starCenterPercent"; - // Tree Model - constexpr auto TreeBottomTopRatioAttribute = "TreeBottomTopRatio"; - constexpr auto TreePerspectiveAttribute = "TreePerspective"; - constexpr auto TreeAttribute = "Tree"; - constexpr auto TreeSpiralsAttribute = "TreeSpirals"; + // Tree Model + constexpr auto BottomTopRatioAttribute = "TreeBottomTopRatio"; + constexpr auto PerspectiveAttribute = "TreePerspective"; + constexpr auto SpiralRotationsAttribute = "TreeSpirals"; + constexpr auto TreeRotationAttribute = "TreeSpiralRotations"; + // Window Frame Model constexpr auto RotationAttribute = "Rotation"; @@ -381,9 +381,7 @@ namespace XmlNodeKeys { constexpr auto SphereType = "Sphere"; constexpr auto SpinnerType = "Spinner"; constexpr auto StarType = "Star"; - constexpr auto Tree360Type = "Tree 360"; - constexpr auto TreeFlatType = "Tree Flat"; - constexpr auto TreeRibbonType = "Tree Ribbon"; + constexpr auto TreeType = "Tree"; constexpr auto WindowType = "Window Frame"; constexpr auto WreathType = "Wreath"; }; @@ -653,6 +651,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::InsideOutAttribute, model.IsInsideOut() ? "1" : "0"); + xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -667,6 +667,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + std::vector cp = model.GetChannelProperies(); + for (auto i = 0; i < cp.size(); i++) { + xmlNode->AddAttribute("ChannelProperties.ChannelColor" + std::to_string(i+1), cp[i]); + } AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -681,6 +685,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::StyleAttribute, model.GetStrandStyle()); + xmlNode->AddAttribute(XmlNodeKeys::CubeStartAttribute, model.GetStrandStart()); + xmlNode->AddAttribute(XmlNodeKeys::StrandPerLineAttribute, model.GetStrandPerLine()); + xmlNode->AddAttribute(XmlNodeKeys::StrandPerLayerAttribute, model.GetStrandPerLayer()); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -695,6 +703,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::CMDepthAttribute, std::to_string(model.GetCustomDepth())); + xmlNode->AddAttribute(XmlNodeKeys::CustomModelAttribute, model.GetCustomData()); + xmlNode->AddAttribute(XmlNodeKeys::BkgImageAttribute, model.GetCustomBackground()); + xmlNode->AddAttribute(XmlNodeKeys::BkgLightnessAttribute, std::to_string(model.GetCustomLightness())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -707,7 +719,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::DropPatternAttribute, model.GetDropPattern()); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -722,6 +736,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::ImageAttribute, model.GetImageFile()); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -736,6 +751,15 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->DeleteAttribute(XmlNodeKeys::DisplayAsAttribute); + if (model.isVerticalMatrix()) { + xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, "Vert Matrix"); + } else { + xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, "Horiz Matrix"); + } + xmlNode->AddAttribute(XmlNodeKeys::LowDefinitionAttribute, std::to_string(model.GetLowDefFactor())); + xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::NoZigZagAttribute, model.IsNoZigZag() ? "true" : "false"); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -764,6 +788,22 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::IndivSegAttribute, model.HasIndivSegs() ? "1" : "0"); + xmlNode->AddAttribute(XmlNodeKeys::DropPatternAttribute, model.GetDropPattern()); + xmlNode->AddAttribute(XmlNodeKeys::NumPointsAttribute, model.GetNumPoints()); + std::vector segSize = model.GetSegmentsSizes(); + for (auto i = 0; i < segSize.size(); i++) { + xmlNode->AddAttribute("Seg" + std::to_string(i + 1), std::to_string(segSize[i] / (segSize.size()+1))); + } + std::vector cSize = model.GetCorners(); + for (auto i = 0; i < cSize.size(); i++) { + xmlNode->AddAttribute("Corner" + std::to_string(i + 1), cSize[i]); + } + xmlNode->AddAttribute(XmlNodeKeys::PointDataAttribute, model.GetPointData()); + xmlNode->AddAttribute(XmlNodeKeys::cPointDataAttribute, model.GetcPointData()); + xmlNode->AddAttribute(XmlNodeKeys::SegsExpandedAttribute, model.AreSegsExpanded() ? "TRUE" : "FALSE"); + xmlNode->AddAttribute(XmlNodeKeys::ModelHeightAttribute, std::to_string(model.GetHeight())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -778,6 +818,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::DegreesAttribute, std::to_string(model.GetSphereDegrees())); + xmlNode->AddAttribute(XmlNodeKeys::StartLatAttribute, std::to_string(model.GetStartLatitude())); + xmlNode->AddAttribute(XmlNodeKeys::EndLatAttribute, std::to_string(model.GetEndLatitude())); + xmlNode->AddAttribute(XmlNodeKeys::LowDefinitionAttribute, std::to_string(model.GetLowDefFactor())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -792,6 +836,11 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::AlternateAttribute, model.HasAlternateNodes() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, model.HasZigZag() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::HallowAttribute, std::to_string(model.GetHollowPercent())); + xmlNode->AddAttribute(XmlNodeKeys::ArcAngleAttribute, std::to_string(model.GetArcAngle())); + xmlNode->AddAttribute(XmlNodeKeys::StartAngleAttribute, std::to_string(model.GetStartAngle())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -806,6 +855,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); + xmlNode->AddAttribute(XmlNodeKeys::StarStartLocationAttribute, model.GetStartLocation()); + xmlNode->AddAttribute(XmlNodeKeys::StarRatioAttribute, std::to_string(model.GetStarRatio())); + xmlNode->AddAttribute(XmlNodeKeys::StarCenterPercentAttribute, std::to_string(model.GetInnerPercent())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -820,6 +873,14 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->DeleteAttribute(XmlNodeKeys::DisplayAsAttribute); + xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, model.GetTreeDescription()); + xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::NoZigZagAttribute, model.IsNoZigZag() ? "true" : "false"); + xmlNode->AddAttribute(XmlNodeKeys::BottomTopRatioAttribute, std::to_string(model.GetBottomTopRatio())); + xmlNode->AddAttribute(XmlNodeKeys::PerspectiveAttribute, std::to_string(model.GetTreePerspective())); + xmlNode->AddAttribute(XmlNodeKeys::SpiralRotationsAttribute, std::to_string(model.GetSpiralRotations())); + xmlNode->AddAttribute(XmlNodeKeys::TreeRotationAttribute, std::to_string(model.GetTreeRotation())); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -828,15 +889,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { parentNode->AddChild(xmlNode); } - // void Visit(const TreeModel &treeflat) override {} - // void Visit(const TreeModel &treeribbon) override {} - void Visit(const WindowFrameModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); //AddThreePointScreenLocationAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::RotationAttribute, model.GetRotation() ? "Counter Clockwise" : "Clockwise"); AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); if (m == nullptr) return; @@ -916,12 +975,8 @@ struct XmlDeserializingObjectFactory { return DeserializeSpinner(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::StarType) { return DeserializeStar(new wxXmlNode(*node), xlights); - } else if (type == XmlNodeKeys::Tree360Type) { - return DeserializeTree360(new wxXmlNode(*node), xlights); - } else if (type == XmlNodeKeys::TreeFlatType) { - return DeserializeTreeFlat(new wxXmlNode(*node), xlights); - } else if (type == XmlNodeKeys::TreeRibbonType) { - return DeserializeTreeRibbon(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::TreeType) { + return DeserializeTree(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::WindowType) { return DeserializeWindow(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::WreathType) { @@ -1104,29 +1159,7 @@ struct XmlDeserializingObjectFactory { return model; } - Model* DeserializeTree360(wxXmlNode* node, xLightsFrame* xlights) { - Model* model; - model = new TreeModel(node, xlights->AllModels, false); - - std::string name = node->GetAttribute("name"); - wxString newname = xlights->AllModels.GenerateModelName(name); - model->SetProperty("name", newname, true); - - return model; - } - - Model* DeserializeTreeFlat(wxXmlNode* node, xLightsFrame* xlights) { - Model* model; - model = new TreeModel(node, xlights->AllModels, false); - - std::string name = node->GetAttribute("name"); - wxString newname = xlights->AllModels.GenerateModelName(name); - model->SetProperty("name", newname, true); - - return model; - } - - Model* DeserializeTreeRibbon(wxXmlNode* node, xLightsFrame* xlights) { + Model* DeserializeTree(wxXmlNode* node, xLightsFrame* xlights) { Model* model; model = new TreeModel(node, xlights->AllModels, false); From be08de96d85c207c993dccdfb083650f14e1e775 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 10 May 2024 00:28:31 -0400 Subject: [PATCH 07/17] XMLSerializer with visitor WIP --- xLights/models/XmlSerializer.h | 150 ++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 70 deletions(-) diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index b2fbbd645d..e8a3a61f56 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -46,11 +46,12 @@ namespace XmlNodeKeys { // Model Node Names constexpr auto ModelsNodeName = "models"; constexpr auto ModelNodeName = "model"; - constexpr auto TypeAttribute = "type"; constexpr auto ExportedAttribute = "exported"; // Common BaseObject Attributes constexpr auto NameAttribute = "name"; + constexpr auto StateNameAttribute = "Name"; //should fix this + constexpr auto FaceNameAttribute = "Name"; //should fix this constexpr auto DisplayAsAttribute = "DisplayAs"; constexpr auto LayoutGroupAttribute = "LayoutGroup"; @@ -76,10 +77,8 @@ namespace XmlNodeKeys { constexpr auto CustomStringsAttribute = "String"; constexpr auto TagColourAttribute = "TagColour"; - // Common SubModel Attributes constexpr auto SubModelNodeName = "subModel"; - constexpr auto SubModelNameAttribute = "name"; constexpr auto LayoutAttribute = "layout"; constexpr auto SMTypeAttribute = "type"; constexpr auto BufferStyleAttribute = "bufferstyle"; @@ -199,6 +198,8 @@ namespace XmlNodeKeys { constexpr auto AlternateNodesAttribute = "AlternateNodes"; constexpr auto LayerSizesAttribute = "LayerSizes"; constexpr auto ZigZagAttribute = "ZigZag"; + constexpr auto CustomColorsAttribute = "CustomColors"; + constexpr auto TypeAttribute = "type"; // Arch Attributes constexpr auto HollowAttribute = "Hollow"; @@ -267,10 +268,9 @@ namespace XmlNodeKeys { constexpr auto AlternateAttribute = "Alternate"; // Star Model - constexpr auto StarStartLocationAttribute = "StarStartLocation"; - constexpr auto StarRatioAttribute = "starRatio"; - constexpr auto StarCenterPercentAttribute = "starCenterPercent"; - + constexpr auto StarStartLocationAttribute = "StarStartLocation"; + constexpr auto StarRatioAttribute = "starRatio"; + constexpr auto StarCenterPercentAttribute = "starCenterPercent"; // Tree Model constexpr auto BottomTopRatioAttribute = "TreeBottomTopRatio"; @@ -282,69 +282,10 @@ namespace XmlNodeKeys { constexpr auto RotationAttribute = "Rotation"; // States - constexpr auto StateAttribute = "stateInfo"; - constexpr auto ColorsAttribute = "Colors"; - constexpr auto sAttribute = "s"; // needs enumeration s1, s2, s3 etc - constexpr auto sColorAttribute = "sColor"; // needs enumeration s1-Color s2-Color, s3-Color etc - constexpr auto sNameAttribute = "sName"; // needs enumeration s1-Name s2-Name, s3-Name etc - + constexpr auto StateNodeName = "stateInfo"; + // Faces - constexpr auto EyesClosedAttribute = "Eyes - Closed"; - constexpr auto EyesClosedColorAttribute = "Eyes - Closed - Color"; - constexpr auto EyesClosed2Attribute = "Eyes - Closed2"; - constexpr auto EyesClosed2ColorAttribute = "Eyes - Closed2 - Color"; - constexpr auto EyesClosed3Attribute = "Eyes - Closed3"; - constexpr auto EyesClosed3ColorAttribute = "Eyes - Closed3 - Color"; - constexpr auto EyesOpenAttribute = "Eyes - Open"; - constexpr auto EyesOpenColorAttribute = "Eyes - Open - Color"; - constexpr auto EyesOpen2Attribute = "Eyes - Open2"; - constexpr auto EyesOpen2ColorAttribute = "Eyes - Open2 - Color"; - constexpr auto EyesOpen3Attribute = "Eyes - Open3"; - constexpr auto EyesOpen3ColorAttribute = "Eyes - Open3 - Color"; - constexpr auto FaceOutlineAttribute = "FaceOutline"; - constexpr auto FaceOutlineColorAttribute = "FaceOutline - Color"; - constexpr auto FaceOutline2Attribute = "FaceOutline2"; - constexpr auto FaceOutline2ColorAttribute = "FaceOutline2 - Color"; - constexpr auto MouthAIAttribute = "Mouth - AI"; - constexpr auto MouthEAttribute = "Mouth - E"; - constexpr auto MouthFVAttribute = "Mouth - FV"; - constexpr auto MouthLAttribute = "Mouth - L"; - constexpr auto MouthMBPAttribute = "Mouth - MBP"; - constexpr auto MouthOAttribute = "Mouth - O"; - constexpr auto MouthUAttribute = "Mouth - U"; - constexpr auto MouthWQAttribute = "Mouth - WQ"; - constexpr auto MouthetcAttribute = "Mouth - etc"; - constexpr auto MouthretAttribute = "Mouth - rest"; - constexpr auto MouthAIColorAttribute = "Mouth - AI-Color"; - constexpr auto MouthEColorAttribute = "Mouth - E-Color"; - constexpr auto MouthFVColorAttribute = "Mouth - FV-Color"; - constexpr auto MouthLColorAttribute = "Mouth - L-Color"; - constexpr auto MouthMBPColorAttribute = "Mouth - MBP-Color"; - constexpr auto MouthOColorAttribute = "Mouth - O-Color"; - constexpr auto MouthUColorAttribute = "Mouth - U-Color"; - constexpr auto MouthWQColorAttribute = "Mouth - WQ-Color"; - constexpr auto MouthetcColorAttribute = "Mouth - etc-Color"; - constexpr auto MouthrestColorAttribute = "Mouth - rest-Color"; - constexpr auto MouthAI2Attribute = "Mouth - AI2"; - constexpr auto MouthE2Attribute = "Mouth - E2"; - constexpr auto MouthFV2Attribute = "Mouth - FV2"; - constexpr auto MouthL2Attribute = "Mouth - L2"; - constexpr auto MouthMBP2Attribute = "Mouth - MBP2"; - constexpr auto MouthO2Attribute = "Mouth - O2"; - constexpr auto MouthU2Attribute = "Mouth - U2"; - constexpr auto MouthWQ2Attribute = "Mouth - WQ2"; - constexpr auto Mouthetc2Attribute = "Mouth - etc2"; - constexpr auto Mouthret2Attribute = "Mouth - rest2"; - constexpr auto MouthAIColor2Attribute = "Mouth - AI2-Color"; - constexpr auto MouthEColor2Attribute = "Mouth - E2-Color"; - constexpr auto MouthFVColor2Attribute = "Mouth - FV2-Color"; - constexpr auto MouthLColor2Attribute = "Mouth - L2-Color"; - constexpr auto MouthMBPColor2Attribute = "Mouth - MBP2-Color"; - constexpr auto MouthOColor2Attribute = "Mouth - O2-Color"; - constexpr auto MouthUColor2Attribute = "Mouth - U2-Color"; - constexpr auto MouthWQColor2Attribute = "Mouth - WQ2-Color"; - constexpr auto MouthetcColor2Attribute = "Mouth - etc2-Color"; - constexpr auto MouthrestColor2Attribute = "Mouth - rest2-Color"; + constexpr auto FaceNodeName = "faceInfo"; // WIP // constexpr auto Attribute = ""; @@ -538,6 +479,71 @@ struct XmlSerializingVisitor : BaseObjectVisitor { return oss; } + void SortAttributes(wxXmlNode* input) { + const wxString attributeToPrioritize = "name"; + std::vector> attributes; + for (wxXmlAttribute* attr = input->GetAttributes(); attr != nullptr; attr = attr->GetNext()) { + attributes.push_back({ std::string(attr->GetName()), std::string(attr->GetValue()) }); + } + /*std::sort(attributes.begin(), attributes.end(), [](const std::pair& a, const std::pair& b) { + return Lower(a.first) < Lower(b.first); + });*/ + auto custom_comparator = [&attributeToPrioritize](const std::pair& a, const std::pair& b) { + if (a.first == attributeToPrioritize) return true; + if (b.first == attributeToPrioritize) return false; + return Lower(a.first) < Lower(b.first); + }; + std::sort(attributes.begin(), attributes.end(), custom_comparator); + wxXmlAttribute* currentAttr = input->GetAttributes(); + while (currentAttr != nullptr) { + wxXmlAttribute* toRemove = currentAttr; + currentAttr = currentAttr->GetNext(); + input->DeleteAttribute(toRemove->GetName()); + } + for (const auto& attr : attributes) { + input->AddAttribute(attr.first, attr.second); + } + } + + void AddFacesandStates(wxXmlNode* node, const Model* m) { + + FaceStateData faces = m->GetFaceInfo(); + for (const auto& f : faces) { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::FaceNodeName); + xmlNode->AddAttribute(XmlNodeKeys::FaceNameAttribute, f.first); + for (const auto& f2 : f.second) { + /*if (f2.first == "CustomColors") { + xmlNode->AddAttribute(XmlNodeKeys::CustomColorsAttribute, f2.second); + } else if (f2.first == "Type") { + xmlNode->AddAttribute(XmlNodeKeys::TypeAttribute, f2.second); + } else if (f2.first != "") { + xmlNode->AddAttribute(f2.first, f2.second); + }*/ + if (f2.first != "") xmlNode->AddAttribute(f2.first, f2.second); + } + SortAttributes(xmlNode); + node->AddChild(xmlNode); + } + + FaceStateData states = m->GetStateInfo(); + for (const auto& s : states) { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::StateNodeName); + xmlNode->AddAttribute(XmlNodeKeys::StateNameAttribute, s.first); + for (const auto& s2 : s.second) { + /*if (s2.first == "CustomColors") { + xmlNode->AddAttribute(XmlNodeKeys::CustomColorsAttribute, s2.second); + } else if (s2.first == "Type") { + xmlNode->AddAttribute(XmlNodeKeys::TypeAttribute, s2.second); + } else if (s2.first != "") { + xmlNode->AddAttribute(s2.first, s2.second); + }*/ + if (s2.first != "") xmlNode->AddAttribute(s2.first, s2.second); + } + SortAttributes(xmlNode); + node->AddChild(xmlNode); + } + } + void AddAliases(wxXmlNode* node, const std::list aliases) { wxXmlNode* aliashdr = new wxXmlNode(wxXML_ELEMENT_NODE, "Aliases"); @@ -558,7 +564,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { wxXmlNode* submodels = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::SubModelNodeName); const SubModel* submodel = dynamic_cast(s); if (submodel == nullptr) return; - submodels->AddAttribute(XmlNodeKeys::SubModelNameAttribute, s->GetName()); + submodels->AddAttribute(XmlNodeKeys::NameAttribute, s->GetName()); submodels->AddAttribute(XmlNodeKeys::LayoutAttribute, submodel->GetSubModelLayout()); submodels->AddAttribute(XmlNodeKeys::SMTypeAttribute, submodel->GetSubModelType()); submodels->AddAttribute(XmlNodeKeys::BufferStyleAttribute, submodel->GetSubModelBufferStyle()); @@ -571,6 +577,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { submodels->AddAttribute("line" + std::to_string(i), nodeInfo[i]); } } + SortAttributes(submodels); AddAliases(submodels, s->GetAliases()); node->AddChild(submodels); } @@ -603,6 +610,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { groups->AddAttribute(XmlNodeKeys::mgyCentreOffsetAttribute, std::to_string(mg1->GetYCentreOffset())); const std::list& aliases = mg1->GetAliases(); AddAliases(groups,aliases); + SortAttributes(groups); node->AddChild(groups); } } @@ -624,6 +632,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { const Model* m = dynamic_cast(&model); AddSubmodels(xmlNode, m); AddGroups(xmlNode, m); + SortAttributes(xmlNode); parentNode->AddChild(xmlNode); } @@ -712,6 +721,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { if (m == nullptr) return; AddSubmodels(xmlNode, m); AddGroups(xmlNode, m); + AddFacesandStates(xmlNode, m); parentNode->AddChild(xmlNode); } void Visit(const IciclesModel& model) override { From 409da8ac4d7f0103b462245b362738ceaa78d323 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 10 May 2024 13:03:10 -0400 Subject: [PATCH 08/17] XMLSerializer with visitor WIP --- xLights/models/XmlSerializer.h | 225 +++++++++++---------------------- 1 file changed, 73 insertions(+), 152 deletions(-) diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index e8a3a61f56..7e940274ca 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -55,6 +55,15 @@ namespace XmlNodeKeys { constexpr auto DisplayAsAttribute = "DisplayAs"; constexpr auto LayoutGroupAttribute = "LayoutGroup"; + // Shared (by some) Attributes + constexpr auto ArcAttribute = "Arc"; + constexpr auto arcAttribute = "arc"; // Arches is lowercase - maybe should be fixed + constexpr auto AlternateNodesAttribute = "AlternateNodes"; + constexpr auto LayerSizesAttribute = "LayerSizes"; + constexpr auto ZigZagAttribute = "ZigZag"; + constexpr auto CustomColorsAttribute = "CustomColors"; + constexpr auto TypeAttribute = "type"; + // Common Model Attributes constexpr auto StartSideAttribute = "StartSide"; constexpr auto DirAttribute = "Dir"; @@ -88,10 +97,7 @@ namespace XmlNodeKeys { // ModelGroup constexpr auto GroupNodeName = "modelGroup"; constexpr auto mgSelectedAttribute = "selected"; - constexpr auto mgLayoutAttribute = "layout"; constexpr auto mgGridSizeAttribute = "GridSize"; - constexpr auto mgLayoutGroupAttribute = "LayoutGroup"; - constexpr auto mgNameAttribute = "name"; constexpr auto mgCentreMinxAttribute = "centreMinx"; constexpr auto mgCentreMinyAttribute = "centreMiny"; constexpr auto mgCentreMaxxAttribute = "centreMaxx"; @@ -103,7 +109,6 @@ namespace XmlNodeKeys { constexpr auto mgxCentreOffsetAttribute = "XCentreOffset"; constexpr auto mgyCentreOffsetAttribute = "YCentreOffset"; constexpr auto mgDefaultCameraAttribute = "DefaultCamera"; - constexpr auto mgTagColourAttribute = "TagColour"; // Size/Position Attributes constexpr auto WorldPosXAttribute = "WorldPosX"; @@ -192,15 +197,6 @@ namespace XmlNodeKeys { constexpr auto MeshOnlyAttribute = "MeshOnly"; constexpr auto BrightnessAttribute = "Brightness"; - // Shared (by some) Attributes - constexpr auto ArcAttribute = "Arc"; - constexpr auto arcAttribute = "arc"; //Arches is lowercase - maybe should be fixed - constexpr auto AlternateNodesAttribute = "AlternateNodes"; - constexpr auto LayerSizesAttribute = "LayerSizes"; - constexpr auto ZigZagAttribute = "ZigZag"; - constexpr auto CustomColorsAttribute = "CustomColors"; - constexpr auto TypeAttribute = "type"; - // Arch Attributes constexpr auto HollowAttribute = "Hollow"; constexpr auto GapAttribute = "Gap"; @@ -209,6 +205,7 @@ namespace XmlNodeKeys { constexpr auto CCHeightAttribute = "CandyCaneHeight"; constexpr auto CCReverseAttribute = "CandyCaneReverse"; constexpr auto CCSticksAttribute = "CandyCaneSticks"; + constexpr auto CCAngleAttribute = "CandyCaneSticks"; // Channel Block Model // Since this is dynamic it all gets done by the visitor @@ -512,13 +509,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::FaceNodeName); xmlNode->AddAttribute(XmlNodeKeys::FaceNameAttribute, f.first); for (const auto& f2 : f.second) { - /*if (f2.first == "CustomColors") { - xmlNode->AddAttribute(XmlNodeKeys::CustomColorsAttribute, f2.second); - } else if (f2.first == "Type") { - xmlNode->AddAttribute(XmlNodeKeys::TypeAttribute, f2.second); - } else if (f2.first != "") { - xmlNode->AddAttribute(f2.first, f2.second); - }*/ if (f2.first != "") xmlNode->AddAttribute(f2.first, f2.second); } SortAttributes(xmlNode); @@ -530,13 +520,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::StateNodeName); xmlNode->AddAttribute(XmlNodeKeys::StateNameAttribute, s.first); for (const auto& s2 : s.second) { - /*if (s2.first == "CustomColors") { - xmlNode->AddAttribute(XmlNodeKeys::CustomColorsAttribute, s2.second); - } else if (s2.first == "Type") { - xmlNode->AddAttribute(XmlNodeKeys::TypeAttribute, s2.second); - } else if (s2.first != "") { - xmlNode->AddAttribute(s2.first, s2.second); - }*/ if (s2.first != "") xmlNode->AddAttribute(s2.first, s2.second); } SortAttributes(xmlNode); @@ -591,13 +574,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { const ModelGroup* mg1 = dynamic_cast(g); if (mg1 == nullptr) return; wxXmlNode* groups = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::GroupNodeName); - groups->AddAttribute(XmlNodeKeys::mgNameAttribute, g->GetName()); + groups->AddAttribute(XmlNodeKeys::NameAttribute, g->GetName()); groups->AddAttribute(XmlNodeKeys::mgModelsAttribute, m->GetName()); - groups->AddAttribute(XmlNodeKeys::mgLayoutGroupAttribute, g->GetLayoutGroup()); + groups->AddAttribute(XmlNodeKeys::LayoutGroupAttribute, g->GetLayoutGroup()); groups->AddAttribute(XmlNodeKeys::mgSelectedAttribute, std::to_string(mg1->IsSelected())); - groups->AddAttribute(XmlNodeKeys::mgLayoutAttribute, mg1->GetLayout()); + groups->AddAttribute(XmlNodeKeys::LayoutAttribute, mg1->GetLayout()); groups->AddAttribute(XmlNodeKeys::mgGridSizeAttribute, std::to_string(mg1->GetGridSize())); - groups->AddAttribute(XmlNodeKeys::mgTagColourAttribute, mg1->GetTagColour().GetAsString(wxC2S_HTML_SYNTAX)); + groups->AddAttribute(XmlNodeKeys::TagColourAttribute, mg1->GetTagColour().GetAsString(wxC2S_HTML_SYNTAX)); groups->AddAttribute(XmlNodeKeys::mgCentreMinxAttribute, std::to_string(mg1->GetCentreMinx())); groups->AddAttribute(XmlNodeKeys::mgCentreMinyAttribute, std::to_string(mg1->GetCentreMiny())); groups->AddAttribute(XmlNodeKeys::mgCentreMaxxAttribute, std::to_string(mg1->GetCentreMaxx())); @@ -617,6 +600,17 @@ struct XmlSerializingVisitor : BaseObjectVisitor { //xmlNode->AddAttribute(XmlNodeKeys::#, std::to_string(#())); + void AddOtherElements(wxXmlNode* xmlNode, const Model* m) + { + SortAttributes(xmlNode); + AddAliases(xmlNode, m->GetAliases()); + AddFacesandStates(xmlNode, m); + AddSubmodels(xmlNode, m); + AddGroups(xmlNode, m); + parentNode->AddChild(xmlNode); + } + + void Visit(const ArchesModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); AddBaseObjectAttributes(model, xmlNode); @@ -628,12 +622,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { xmlNode->AddAttribute(XmlNodeKeys::GapAttribute, std::to_string(model.GetGap())); xmlNode->AddAttribute(XmlNodeKeys::arcAttribute, std::to_string(model.GetArc())); xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - SortAttributes(xmlNode); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const CandyCaneModel& model) override { @@ -641,17 +631,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::CCHeightAttribute, std::to_string(model.GetCandyCaneHeight())); xmlNode->AddAttribute(XmlNodeKeys::CCReverseAttribute, model.IsReverse() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::CCSticksAttribute, model.IsSticks() ? "true": "false"); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const CircleModel& model) override { @@ -659,15 +645,11 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::InsideOutAttribute, model.IsInsideOut() ? "1" : "0"); xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const ChannelBlockModel& model) override { @@ -675,17 +657,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); std::vector cp = model.GetChannelProperies(); for (auto i = 0; i < cp.size(); i++) { xmlNode->AddAttribute("ChannelProperties.ChannelColor" + std::to_string(i+1), cp[i]); } - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const CubeModel& model) override { @@ -693,17 +671,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::StyleAttribute, model.GetStrandStyle()); xmlNode->AddAttribute(XmlNodeKeys::CubeStartAttribute, model.GetStrandStart()); xmlNode->AddAttribute(XmlNodeKeys::StrandPerLineAttribute, model.GetStrandPerLine()); xmlNode->AddAttribute(XmlNodeKeys::StrandPerLayerAttribute, model.GetStrandPerLayer()); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const CustomModel& model) override { @@ -711,18 +685,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::CMDepthAttribute, std::to_string(model.GetCustomDepth())); xmlNode->AddAttribute(XmlNodeKeys::CustomModelAttribute, model.GetCustomData()); xmlNode->AddAttribute(XmlNodeKeys::BkgImageAttribute, model.GetCustomBackground()); xmlNode->AddAttribute(XmlNodeKeys::BkgLightnessAttribute, std::to_string(model.GetCustomLightness())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - AddFacesandStates(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const IciclesModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); @@ -732,12 +701,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::DropPatternAttribute, model.GetDropPattern()); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const ImageModel& model) override { @@ -745,14 +710,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::ImageAttribute, model.GetImageFile()); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const MatrixModel& model) override { @@ -760,7 +721,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->DeleteAttribute(XmlNodeKeys::DisplayAsAttribute); if (model.isVerticalMatrix()) { xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, "Vert Matrix"); @@ -770,12 +731,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { xmlNode->AddAttribute(XmlNodeKeys::LowDefinitionAttribute, std::to_string(model.GetLowDefFactor())); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::NoZigZagAttribute, model.IsNoZigZag() ? "true" : "false"); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const SingleLineModel& model) override { @@ -783,13 +740,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); - AddAliases(xmlNode, model.GetAliases()); + AddThreePointScreenLocationAttributes(model, xmlNode); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const PolyLineModel& model) override { @@ -797,7 +750,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::IndivSegAttribute, model.HasIndivSegs() ? "1" : "0"); xmlNode->AddAttribute(XmlNodeKeys::DropPatternAttribute, model.GetDropPattern()); @@ -814,12 +767,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { xmlNode->AddAttribute(XmlNodeKeys::cPointDataAttribute, model.GetcPointData()); xmlNode->AddAttribute(XmlNodeKeys::SegsExpandedAttribute, model.AreSegsExpanded() ? "TRUE" : "FALSE"); xmlNode->AddAttribute(XmlNodeKeys::ModelHeightAttribute, std::to_string(model.GetHeight())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const SphereModel& model) override { @@ -827,17 +776,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::DegreesAttribute, std::to_string(model.GetSphereDegrees())); xmlNode->AddAttribute(XmlNodeKeys::StartLatAttribute, std::to_string(model.GetStartLatitude())); xmlNode->AddAttribute(XmlNodeKeys::EndLatAttribute, std::to_string(model.GetEndLatitude())); xmlNode->AddAttribute(XmlNodeKeys::LowDefinitionAttribute, std::to_string(model.GetLowDefFactor())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const SpinnerModel& model) override { @@ -845,18 +790,14 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::AlternateAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, model.HasZigZag() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::HallowAttribute, std::to_string(model.GetHollowPercent())); xmlNode->AddAttribute(XmlNodeKeys::ArcAngleAttribute, std::to_string(model.GetArcAngle())); xmlNode->AddAttribute(XmlNodeKeys::StartAngleAttribute, std::to_string(model.GetStartAngle())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const StarModel& model) override { @@ -864,17 +805,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); xmlNode->AddAttribute(XmlNodeKeys::StarStartLocationAttribute, model.GetStartLocation()); xmlNode->AddAttribute(XmlNodeKeys::StarRatioAttribute, std::to_string(model.GetStarRatio())); xmlNode->AddAttribute(XmlNodeKeys::StarCenterPercentAttribute, std::to_string(model.GetInnerPercent())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const TreeModel& model) override { @@ -882,7 +819,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->DeleteAttribute(XmlNodeKeys::DisplayAsAttribute); xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, model.GetTreeDescription()); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); @@ -891,12 +828,8 @@ struct XmlSerializingVisitor : BaseObjectVisitor { xmlNode->AddAttribute(XmlNodeKeys::PerspectiveAttribute, std::to_string(model.GetTreePerspective())); xmlNode->AddAttribute(XmlNodeKeys::SpiralRotationsAttribute, std::to_string(model.GetSpiralRotations())); xmlNode->AddAttribute(XmlNodeKeys::TreeRotationAttribute, std::to_string(model.GetTreeRotation())); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const WindowFrameModel& model) override { @@ -904,14 +837,10 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::RotationAttribute, model.GetRotation() ? "Counter Clockwise" : "Clockwise"); - AddAliases(xmlNode, model.GetAliases()); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } void Visit(const WreathModel& model) override { @@ -919,35 +848,27 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - //AddThreePointScreenLocationAttributes(model, xmlNode); - AddAliases(xmlNode, model.GetAliases()); + AddThreePointScreenLocationAttributes(model, xmlNode); const Model* m = dynamic_cast(&model); - if (m == nullptr) return; - AddSubmodels(xmlNode, m); - AddGroups(xmlNode, m); - parentNode->AddChild(xmlNode); + AddOtherElements(xmlNode, m); } - void Visit(const DmxMovingHeadAdv& moving_head) override { - wxXmlNode* mhNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); - AddBaseObjectAttributes(moving_head, mhNode); - AddCommonModelAttributes(moving_head, mhNode); - AddModelScreenLocationAttributes(moving_head, mhNode); - AddColorAttributes(moving_head, mhNode); - mhNode->AddAttribute(XmlNodeKeys::DmxFixturelAttribute, moving_head.GetFixture()); - mhNode->AddAttribute(XmlNodeKeys::DmxBeamYOffsetAttribute, std::to_string(moving_head.GetBeamYOffset())); - mhNode->AddAttribute(XmlNodeKeys::DmxBeamLengthAttribute, std::to_string(moving_head.GetBeamLength())); - AddDmxMotorAttributes(reinterpret_cast(moving_head.GetPanMotor()), mhNode); - AddDmxMotorAttributes(reinterpret_cast(moving_head.GetTiltMotor()), mhNode); - AddMeshAttributes(reinterpret_cast(moving_head.GetBaseMesh()), mhNode); - AddMeshAttributes(reinterpret_cast(moving_head.GetYokeMesh()), mhNode); - AddMeshAttributes(reinterpret_cast(moving_head.GetHeadMesh()), mhNode); - const Model* m = dynamic_cast(&moving_head); - if (m == nullptr) - return; - AddSubmodels(mhNode, m); - AddGroups(mhNode, m); - parentNode->AddChild(mhNode); + void Visit(const DmxMovingHeadAdv& model) override { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); + AddBaseObjectAttributes(model, xmlNode); + AddCommonModelAttributes(model, xmlNode); + AddModelScreenLocationAttributes(model, xmlNode); + AddColorAttributes(model, xmlNode); + xmlNode->AddAttribute(XmlNodeKeys::DmxFixturelAttribute, model.GetFixture()); + xmlNode->AddAttribute(XmlNodeKeys::DmxBeamYOffsetAttribute, std::to_string(model.GetBeamYOffset())); + xmlNode->AddAttribute(XmlNodeKeys::DmxBeamLengthAttribute, std::to_string(model.GetBeamLength())); + AddDmxMotorAttributes(reinterpret_cast(model.GetPanMotor()), xmlNode); + AddDmxMotorAttributes(reinterpret_cast(model.GetTiltMotor()), xmlNode); + AddMeshAttributes(reinterpret_cast(model.GetBaseMesh()), xmlNode); + AddMeshAttributes(reinterpret_cast(model.GetYokeMesh()), xmlNode); + AddMeshAttributes(reinterpret_cast(model.GetHeadMesh()), xmlNode); + const Model* m = dynamic_cast(&model); + AddOtherElements(xmlNode, m); } }; From 6548819de986bb8e136b2b29988241478503d3d4 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 10 May 2024 18:16:58 -0400 Subject: [PATCH 09/17] XMLSerializer with visitor WIP --- xLights/models/XmlSerializer.h | 49 +++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 7e940274ca..602b0cb6bb 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -21,6 +21,7 @@ #include "CircleModel.h" #include "CubeModel.h" #include "CustomModel.h" +#include "DimmingCurve.h" #include "IciclesModel.h" #include "ImageModel.h" #include "MatrixModel.h" @@ -59,6 +60,8 @@ namespace XmlNodeKeys { constexpr auto ArcAttribute = "Arc"; constexpr auto arcAttribute = "arc"; // Arches is lowercase - maybe should be fixed constexpr auto AlternateNodesAttribute = "AlternateNodes"; + constexpr auto BrightnessAttribute = "Brightness"; //should fix + constexpr auto DCBrightnessAttribute = "brightness"; //shoudl fix constexpr auto LayerSizesAttribute = "LayerSizes"; constexpr auto ZigZagAttribute = "ZigZag"; constexpr auto CustomColorsAttribute = "CustomColors"; @@ -195,7 +198,6 @@ namespace XmlNodeKeys { // Mesh Attributes constexpr auto ObjFileAttribute = "ObjFile"; constexpr auto MeshOnlyAttribute = "MeshOnly"; - constexpr auto BrightnessAttribute = "Brightness"; // Arch Attributes constexpr auto HollowAttribute = "Hollow"; @@ -221,7 +223,6 @@ namespace XmlNodeKeys { // Custom Model constexpr auto CustomModelAttribute = "CustomModel"; - constexpr auto CMBrightnessAttribute = "Brightness"; constexpr auto StrandsAttribute = "Strands"; constexpr auto NodesAttribute = "Nodes"; constexpr auto PixelCountAttribute = "PixelCount"; @@ -233,6 +234,9 @@ namespace XmlNodeKeys { constexpr auto BkgAttribute = "Bkg"; constexpr auto CMDepthAttribute = "Depth"; + // Dimming Curves + constexpr auto DimmingNodeName = "dimmingCurve"; + // Image Model constexpr auto ImageAttribute = "Image"; constexpr auto BlackAttribute = "Black"; @@ -374,6 +378,16 @@ struct XmlSerializingVisitor : BaseObjectVisitor { node->AddAttribute(XmlNodeKeys::LockedAttribute, std::to_string(locked)); } + void AddTwoPointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { + const TwoPointScreenLocation& screenLoc = dynamic_cast(base.GetBaseObjectScreenLocation()); + float x2 = screenLoc.GetX2(); + float y2 = screenLoc.GetY2(); + float z2 = screenLoc.GetZ2(); + node->AddAttribute(XmlNodeKeys::X2Attribute, std::to_string(x2)); + node->AddAttribute(XmlNodeKeys::Y2Attribute, std::to_string(y2)); + node->AddAttribute(XmlNodeKeys::Z2Attribute, std::to_string(z2)); + } + void AddThreePointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { const ThreePointScreenLocation& screenLoc = dynamic_cast(base.GetBaseObjectScreenLocation()); float x2 = screenLoc.GetX2(); @@ -540,6 +554,20 @@ struct XmlSerializingVisitor : BaseObjectVisitor { } } + void AddDimmingCurve(wxXmlNode* node, const Model* m) { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::DimmingNodeName); + + std::map> dcInfo = m->GetDimmingInfo(); + for (const auto& d1 : dcInfo) { + wxXmlNode* dc = new wxXmlNode(wxXML_ELEMENT_NODE, d1.first); + for (const auto& d2 : d1.second) { + dc->AddAttribute(d2.first, d2.second); + xmlNode->AddChild(dc); + } + } + node->AddChild(xmlNode); + } + void AddSubmodels(wxXmlNode* node, const Model* m) { const std::vector& submodelList = m->GetSubModels(); @@ -604,6 +632,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { { SortAttributes(xmlNode); AddAliases(xmlNode, m->GetAliases()); + AddDimmingCurve(xmlNode,m); AddFacesandStates(xmlNode, m); AddSubmodels(xmlNode, m); AddGroups(xmlNode, m); @@ -645,7 +674,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::InsideOutAttribute, model.IsInsideOut() ? "1" : "0"); xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); const Model* m = dynamic_cast(&model); @@ -657,7 +685,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); + AddTwoPointScreenLocationAttributes(model, xmlNode); std::vector cp = model.GetChannelProperies(); for (auto i = 0; i < cp.size(); i++) { xmlNode->AddAttribute("ChannelProperties.ChannelColor" + std::to_string(i+1), cp[i]); @@ -671,7 +699,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::StyleAttribute, model.GetStrandStyle()); xmlNode->AddAttribute(XmlNodeKeys::CubeStartAttribute, model.GetStrandStart()); xmlNode->AddAttribute(XmlNodeKeys::StrandPerLineAttribute, model.GetStrandPerLine()); @@ -685,7 +712,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::CMDepthAttribute, std::to_string(model.GetCustomDepth())); xmlNode->AddAttribute(XmlNodeKeys::CustomModelAttribute, model.GetCustomData()); xmlNode->AddAttribute(XmlNodeKeys::BkgImageAttribute, model.GetCustomBackground()); @@ -710,7 +736,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::ImageAttribute, model.GetImageFile()); const Model* m = dynamic_cast(&model); AddOtherElements(xmlNode, m); @@ -721,7 +746,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->DeleteAttribute(XmlNodeKeys::DisplayAsAttribute); if (model.isVerticalMatrix()) { xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, "Vert Matrix"); @@ -740,7 +764,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); + AddTwoPointScreenLocationAttributes(model, xmlNode); const Model* m = dynamic_cast(&model); AddOtherElements(xmlNode, m); } @@ -750,7 +774,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::IndivSegAttribute, model.HasIndivSegs() ? "1" : "0"); xmlNode->AddAttribute(XmlNodeKeys::DropPatternAttribute, model.GetDropPattern()); @@ -776,7 +799,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::DegreesAttribute, std::to_string(model.GetSphereDegrees())); xmlNode->AddAttribute(XmlNodeKeys::StartLatAttribute, std::to_string(model.GetStartLatitude())); xmlNode->AddAttribute(XmlNodeKeys::EndLatAttribute, std::to_string(model.GetEndLatitude())); @@ -790,7 +812,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::AlternateAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, model.HasZigZag() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::HallowAttribute, std::to_string(model.GetHollowPercent())); @@ -805,7 +826,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::LayerSizesAttribute, vectorToString(model.GetLayerSizes())); xmlNode->AddAttribute(XmlNodeKeys::StarStartLocationAttribute, model.GetStartLocation()); xmlNode->AddAttribute(XmlNodeKeys::StarRatioAttribute, std::to_string(model.GetStarRatio())); @@ -819,7 +839,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->DeleteAttribute(XmlNodeKeys::DisplayAsAttribute); xmlNode->AddAttribute(XmlNodeKeys::DisplayAsAttribute, model.GetTreeDescription()); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); @@ -837,7 +856,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::RotationAttribute, model.GetRotation() ? "Counter Clockwise" : "Clockwise"); const Model* m = dynamic_cast(&model); AddOtherElements(xmlNode, m); @@ -848,7 +866,6 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); const Model* m = dynamic_cast(&model); AddOtherElements(xmlNode, m); } From 56a4c244247bcf581268d0a81a79cdc721d99be7 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 12 May 2024 13:33:03 -0400 Subject: [PATCH 10/17] XMLSerializer with visitor WIP + CustomModel2.0 --- xLights/LayoutPanel.cpp | 2 +- xLights/models/CustomModel.h | 1 + xLights/models/Model.cpp | 19 ++- xLights/models/Model.h | 5 + xLights/models/XmlSerializer.h | 254 +++++++++++++++++++++++++++++---- 5 files changed, 249 insertions(+), 32 deletions(-) diff --git a/xLights/LayoutPanel.cpp b/xLights/LayoutPanel.cpp index 5d5f874d72..f6a4457300 100644 --- a/xLights/LayoutPanel.cpp +++ b/xLights/LayoutPanel.cpp @@ -3664,7 +3664,7 @@ void LayoutPanel::FinalizeModel() // Models that support visitors don't use the ImportXlightsModel method // If there are import issues we need to try to fix them inside the XmlSerializer - if (!_newModel->SupportsVisitors()) { + if (!_newModel->SupportsVisitors() || !XmlSerializer::IsXmlSerializerFormat(_newModel->GetModelXml())) { xlights->AddTraceMessage("LayoutPanel::FinalizeModel Do the import. " + _lastXlightsModel); xlights->AddTraceMessage("LayoutPanel::FinalizeModel Model type " + _newModel->GetDisplayAs()); _newModel->ImportXlightsModel(_lastXlightsModel, xlights, min_x, max_x, min_y, max_y); diff --git a/xLights/models/CustomModel.h b/xLights/models/CustomModel.h index cb167b6c75..94a9ed3cd1 100644 --- a/xLights/models/CustomModel.h +++ b/xLights/models/CustomModel.h @@ -69,6 +69,7 @@ class CustomModel : public ModelWithScreenLocation virtual std::string GetNodeName(size_t x, bool def = false) const override; virtual std::list CheckModelSettings() override; virtual int NodesPerString(int string) const override; + std::vector>> GetLocations() const { return locations; } virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } diff --git a/xLights/models/Model.cpp b/xLights/models/Model.cpp index 4b07a067e9..0e79791f15 100644 --- a/xLights/models/Model.cpp +++ b/xLights/models/Model.cpp @@ -6363,7 +6363,7 @@ Model* Model::GetXlightsModel(Model* model, std::string& last_model, xLightsFram wxXmlNode* root = doc.GetRoot(); // check for XmlSerializer format - if (root->GetAttribute(XmlNodeKeys::TypeAttribute, "") == XmlNodeKeys::ExportedAttribute) { + if (XmlSerializer::IsXmlSerializerFormat(root)) { // grab the attributes I want to keep std::string startChannel = model->GetModelXml()->GetAttribute("StartChannel", "1").ToStdString(); auto x = model->GetHcenterPos(); @@ -7309,6 +7309,23 @@ std::string Model::GetControllerName() const return ModelXml->GetAttribute("Controller", "").Trim(true).Trim(false).ToStdString(); } +std::string Model::GetControllerGamma() const { + return GetControllerConnection()->GetAttribute("gamma", "0.0").ToStdString(); +} + +int Model::GetControllerReverse() const { + return wxAtoi(GetControllerConnection()->GetAttribute("reverse", "0")); +} + +int Model::GetControllerZigZag() const { + return wxAtoi(GetControllerConnection()->GetAttribute("zigZag", "0")); +} + +std::string Model::GetRGBWHandling() const { + return ModelXml->GetAttribute("RGBWHandling", "").ToStdString(); +} + + // std::list Model::GetProtocols() //{ // std::list res; diff --git a/xLights/models/Model.h b/xLights/models/Model.h index a1d88c3296..7675a7430d 100644 --- a/xLights/models/Model.h +++ b/xLights/models/Model.h @@ -384,6 +384,11 @@ class Model : public BaseObject [[nodiscard]] int GetControllerEndNulls() const; [[nodiscard]] wxString GetControllerColorOrder() const; [[nodiscard]] int GetControllerGroupCount() const; + [[nodiscard]] std::string GetControllerGamma() const; + [[nodiscard]] int GetControllerZigZag() const; + [[nodiscard]] int GetControllerReverse() const; + [[nodiscard]] std::string GetRGBWHandling() const; + void SetControllerStartNulls(int nulls); void SetControllerEndNulls(int nulls); void SetControllerColorOrder(wxString const& color); diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 602b0cb6bb..02e866b8b9 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -35,6 +35,7 @@ #include "SubModel.h" #include "ThreePointScreenLocation.h" #include "TreeModel.h" +#include "ViewObjectManager.h" #include "WindowFrameModel.h" #include "WreathModel.h" #include "DMX/DmxColorAbilityCMY.h" @@ -63,9 +64,12 @@ namespace XmlNodeKeys { constexpr auto BrightnessAttribute = "Brightness"; //should fix constexpr auto DCBrightnessAttribute = "brightness"; //shoudl fix constexpr auto LayerSizesAttribute = "LayerSizes"; - constexpr auto ZigZagAttribute = "ZigZag"; + constexpr auto ZigZagAttribute = "ZigZag"; //fix it + constexpr auto CZigZagAttribute = "zigZag"; //fix it constexpr auto CustomColorsAttribute = "CustomColors"; constexpr auto TypeAttribute = "type"; + constexpr auto CReverseAttribute = "reverse"; //fix it + constexpr auto ReverseAttribute = "Reverse"; //fix it // Common Model Attributes constexpr auto StartSideAttribute = "StartSide"; @@ -76,6 +80,7 @@ namespace XmlNodeKeys { constexpr auto AntialiasAttribute = "Antialias"; constexpr auto PixelSizeAttribute = "PixelSize"; constexpr auto StringTypeAttribute = "StringType"; + constexpr auto RGBWHandleAttribute = "RGBWHandling"; constexpr auto TransparencyAttribute = "Transparency"; constexpr auto BTransparencyAttribute = "BlackTransparency"; constexpr auto StartChannelAttribute = "StartChannel"; @@ -88,6 +93,8 @@ namespace XmlNodeKeys { constexpr auto DescriptionAttribute = "Description"; constexpr auto CustomStringsAttribute = "String"; constexpr auto TagColourAttribute = "TagColour"; + constexpr auto PixelStyleAttribute = "PixelStyle"; + // Common SubModel Attributes constexpr auto SubModelNodeName = "subModel"; @@ -182,18 +189,23 @@ namespace XmlNodeKeys { constexpr auto OrientZeroAttribute = "OrientZero"; constexpr auto OrientHomeAttribute = "OrientHome"; constexpr auto SlewLimitAttribute = "SlewLimit"; - constexpr auto ReverseAttribute = "Reverse"; constexpr auto UpsideDownAttribute = "UpsideDown"; // Servo Model // TBC // Controller - constexpr auto ConnectionAttribute = "Connection"; - constexpr auto ProtocolAttribute = "Protocol"; - constexpr auto PortAttribute = "Port"; - constexpr auto StartNullAttribute = "startNull"; - constexpr auto EndNullAttribute = "endNull"; + constexpr auto CtrlConnectionName = "ControllerConnection"; + constexpr auto ProtocolAttribute = "Protocol"; + constexpr auto PortAttribute = "Port"; + constexpr auto StartNullAttribute = "nullNodes"; + constexpr auto EndNullAttribute = "endNullNodes"; + constexpr auto GammaAttribute = "gamma"; + constexpr auto ColorOrderAttribute = "colorOrder"; + constexpr auto GroupCountAttribute = "groupCount"; + constexpr auto SmartRemoteTypeAttribute = "SmartRemoteType"; + constexpr auto SmartRemoteAttribute = "SmartRemote"; + // Mesh Attributes constexpr auto ObjFileAttribute = "ObjFile"; @@ -326,6 +338,17 @@ namespace XmlNodeKeys { constexpr auto TreeType = "Tree"; constexpr auto WindowType = "Window Frame"; constexpr auto WreathType = "Wreath"; + + //Extra Objects + constexpr auto ViewObjectsType = "view_objects"; + constexpr auto EffectsType = "effects"; + constexpr auto ViewsType = "views"; + constexpr auto PalettesType = "palettes"; + constexpr auto LayoutGroupsType = "layoutGroups"; + constexpr auto PerspectivesType = "perspectives"; + constexpr auto SettingsType = "settings"; + constexpr auto ColorsType = "colors"; + constexpr auto ViewPointsType = "Viewpoints"; }; struct XmlSerializingVisitor : BaseObjectVisitor { @@ -349,6 +372,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { node->AddAttribute(XmlNodeKeys::Parm3Attribute, std::to_string(model.GetParm3())); node->AddAttribute(XmlNodeKeys::AntialiasAttribute, std::to_string((long)model.GetPixelStyle())); node->AddAttribute(XmlNodeKeys::PixelSizeAttribute, std::to_string(model.GetPixelSize())); + node->AddAttribute(XmlNodeKeys::PixelStyleAttribute, model.GetPixelStyleDescription(model.GetPixelStyle())); + node->AddAttribute(XmlNodeKeys::RGBWHandleAttribute, model.GetRGBWHandling()); + node->AddAttribute(XmlNodeKeys::ActiveAttribute, std::to_string(model.IsActive())); node->AddAttribute(XmlNodeKeys::StringTypeAttribute, model.GetStringType()); node->AddAttribute(XmlNodeKeys::TransparencyAttribute, std::to_string(model.GetTransparency())); node->AddAttribute(XmlNodeKeys::BTransparencyAttribute, std::to_string(model.GetBlackTransparency())); @@ -378,7 +404,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { node->AddAttribute(XmlNodeKeys::LockedAttribute, std::to_string(locked)); } - void AddTwoPointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { + /*void AddTwoPointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { const TwoPointScreenLocation& screenLoc = dynamic_cast(base.GetBaseObjectScreenLocation()); float x2 = screenLoc.GetX2(); float y2 = screenLoc.GetY2(); @@ -386,9 +412,9 @@ struct XmlSerializingVisitor : BaseObjectVisitor { node->AddAttribute(XmlNodeKeys::X2Attribute, std::to_string(x2)); node->AddAttribute(XmlNodeKeys::Y2Attribute, std::to_string(y2)); node->AddAttribute(XmlNodeKeys::Z2Attribute, std::to_string(z2)); - } + }*/ - void AddThreePointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node) { + void AddThreePointScreenLocationAttributes(const BaseObject& base, wxXmlNode* node, const int threePts) { const ThreePointScreenLocation& screenLoc = dynamic_cast(base.GetBaseObjectScreenLocation()); float x2 = screenLoc.GetX2(); float y2 = screenLoc.GetY2(); @@ -396,11 +422,13 @@ struct XmlSerializingVisitor : BaseObjectVisitor { node->AddAttribute(XmlNodeKeys::X2Attribute, std::to_string(x2)); node->AddAttribute(XmlNodeKeys::Y2Attribute, std::to_string(y2)); node->AddAttribute(XmlNodeKeys::Z2Attribute, std::to_string(z2)); - int angle = screenLoc.GetAngle(); - node->AddAttribute(XmlNodeKeys::AngleAttribute, std::to_string(angle)); - float shear = screenLoc.GetYShear(); - node->AddAttribute(XmlNodeKeys::ShearAttribute, std::to_string(shear)); - node->AddAttribute(XmlNodeKeys::HeightAttribute, std::to_string(base.GetHeight())); + if (threePts == 3) { + int angle = screenLoc.GetAngle(); + node->AddAttribute(XmlNodeKeys::AngleAttribute, std::to_string(angle)); + float shear = screenLoc.GetYShear(); + node->AddAttribute(XmlNodeKeys::ShearAttribute, std::to_string(shear)); + node->AddAttribute(XmlNodeKeys::HeightAttribute, std::to_string(base.GetHeight())); + } } void AddColorAbilityRGBAttributes(const DmxColorAbilityRGB* colors, wxXmlNode* node) { @@ -492,6 +520,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { void SortAttributes(wxXmlNode* input) { const wxString attributeToPrioritize = "name"; + const wxString attributeToDePrioritize = "CustomModel"; std::vector> attributes; for (wxXmlAttribute* attr = input->GetAttributes(); attr != nullptr; attr = attr->GetNext()) { attributes.push_back({ std::string(attr->GetName()), std::string(attr->GetValue()) }); @@ -499,9 +528,11 @@ struct XmlSerializingVisitor : BaseObjectVisitor { /*std::sort(attributes.begin(), attributes.end(), [](const std::pair& a, const std::pair& b) { return Lower(a.first) < Lower(b.first); });*/ - auto custom_comparator = [&attributeToPrioritize](const std::pair& a, const std::pair& b) { + auto custom_comparator = [&attributeToPrioritize, &attributeToDePrioritize](const std::pair& a, const std::pair& b) { if (a.first == attributeToPrioritize) return true; if (b.first == attributeToPrioritize) return false; + if (a.first.Contains(attributeToDePrioritize)) return false; + if (b.first.Contains(attributeToDePrioritize)) return true; return Lower(a.first) < Lower(b.first); }; std::sort(attributes.begin(), attributes.end(), custom_comparator); @@ -555,17 +586,19 @@ struct XmlSerializingVisitor : BaseObjectVisitor { } void AddDimmingCurve(wxXmlNode* node, const Model* m) { - wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::DimmingNodeName); - std::map> dcInfo = m->GetDimmingInfo(); - for (const auto& d1 : dcInfo) { - wxXmlNode* dc = new wxXmlNode(wxXML_ELEMENT_NODE, d1.first); - for (const auto& d2 : d1.second) { - dc->AddAttribute(d2.first, d2.second); - xmlNode->AddChild(dc); + if (dcInfo.size() != 0) { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::DimmingNodeName); + + for (const auto& d1 : dcInfo) { + wxXmlNode* dc = new wxXmlNode(wxXML_ELEMENT_NODE, d1.first); + for (const auto& d2 : d1.second) { + dc->AddAttribute(d2.first, d2.second); + xmlNode->AddChild(dc); + } } + node->AddChild(xmlNode); } - node->AddChild(xmlNode); } void AddSubmodels(wxXmlNode* node, const Model* m) { @@ -626,6 +659,26 @@ struct XmlSerializingVisitor : BaseObjectVisitor { } } + void AddControllerConnection(wxXmlNode* node, const Model* m) { + int p = m->GetControllerPort(); + if (p != 0) { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::CtrlConnectionName); + xmlNode->AddAttribute(XmlNodeKeys::ProtocolAttribute, m->GetControllerProtocol()); + xmlNode->AddAttribute(XmlNodeKeys::PortAttribute, std::to_string(m->GetControllerPort())); + xmlNode->AddAttribute(XmlNodeKeys::StartNullAttribute, std::to_string(m->GetControllerStartNulls())); + xmlNode->AddAttribute(XmlNodeKeys::EndNullAttribute, std::to_string(m->GetControllerEndNulls())); + xmlNode->AddAttribute(XmlNodeKeys::BrightnessAttribute, std::to_string(m->GetControllerBrightness())); + xmlNode->AddAttribute(XmlNodeKeys::GammaAttribute, m->GetControllerGamma()); + xmlNode->AddAttribute(XmlNodeKeys::ColorOrderAttribute, m->GetControllerColorOrder()); + xmlNode->AddAttribute(XmlNodeKeys::CReverseAttribute, std::to_string(m->GetControllerReverse())); + xmlNode->AddAttribute(XmlNodeKeys::CZigZagAttribute, std::to_string(m->GetControllerZigZag())); + xmlNode->AddAttribute(XmlNodeKeys::GroupCountAttribute, std::to_string(m->GetControllerGroupCount())); + xmlNode->AddAttribute(XmlNodeKeys::SmartRemoteTypeAttribute, m->GetSmartRemoteType()); + xmlNode->AddAttribute(XmlNodeKeys::SmartRemoteAttribute, std::to_string(m->GetSmartRemote())); + node->AddChild(xmlNode); + } + } + //xmlNode->AddAttribute(XmlNodeKeys::#, std::to_string(#())); void AddOtherElements(wxXmlNode* xmlNode, const Model* m) @@ -636,6 +689,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddFacesandStates(xmlNode, m); AddSubmodels(xmlNode, m); AddGroups(xmlNode, m); + AddControllerConnection(xmlNode, m); parentNode->AddChild(xmlNode); } @@ -645,7 +699,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode, 3); xmlNode->AddAttribute(XmlNodeKeys::ZigZagAttribute, model.GetZigZag() ? "true": "false"); xmlNode->AddAttribute(XmlNodeKeys::HollowAttribute, std::to_string(model.GetHollow())); xmlNode->AddAttribute(XmlNodeKeys::GapAttribute, std::to_string(model.GetGap())); @@ -660,7 +714,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode, 3); xmlNode->AddAttribute(XmlNodeKeys::CCHeightAttribute, std::to_string(model.GetCandyCaneHeight())); xmlNode->AddAttribute(XmlNodeKeys::CCReverseAttribute, model.IsReverse() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::CCSticksAttribute, model.IsSticks() ? "true": "false"); @@ -685,7 +739,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddTwoPointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode, 2); std::vector cp = model.GetChannelProperies(); for (auto i = 0; i < cp.size(); i++) { xmlNode->AddAttribute("ChannelProperties.ChannelColor" + std::to_string(i+1), cp[i]); @@ -716,15 +770,33 @@ struct XmlSerializingVisitor : BaseObjectVisitor { xmlNode->AddAttribute(XmlNodeKeys::CustomModelAttribute, model.GetCustomData()); xmlNode->AddAttribute(XmlNodeKeys::BkgImageAttribute, model.GetCustomBackground()); xmlNode->AddAttribute(XmlNodeKeys::BkgLightnessAttribute, std::to_string(model.GetCustomLightness())); + std::vector>> locations = model.GetLocations(); + std::string cm2 = ""; + for (auto l = 0; l < locations.size(); l++) { + for (auto h = 0; h < locations[l].size(); h++) { + for (auto w = 0; w < locations[l][h].size(); w++) { + if (locations.size() == 1) { + if (locations[l][h][w] != -1) + cm2 += std::to_string(h) + "," + std::to_string(w) + "," + std::to_string(locations[l][h][w]) + ","; + } else { + if (locations[l][h][w] != -1) + cm2 += std::to_string(l) + "," + std::to_string(h) + "," + std::to_string(w) + "," + std::to_string(locations[l][h][w]) + ","; + } + } + } + } + xmlNode->AddAttribute("CustomModel2.0", cm2); const Model* m = dynamic_cast(&model); AddOtherElements(xmlNode, m); + + } void Visit(const IciclesModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddThreePointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode, 3); xmlNode->AddAttribute(XmlNodeKeys::AlternateNodesAttribute, model.HasAlternateNodes() ? "true" : "false"); xmlNode->AddAttribute(XmlNodeKeys::DropPatternAttribute, model.GetDropPattern()); const Model* m = dynamic_cast(&model); @@ -764,7 +836,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddBaseObjectAttributes(model, xmlNode); AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); - AddTwoPointScreenLocationAttributes(model, xmlNode); + AddThreePointScreenLocationAttributes(model, xmlNode, 2); const Model* m = dynamic_cast(&model); AddOtherElements(xmlNode, m); } @@ -928,7 +1000,23 @@ struct XmlDeserializingObjectFactory { } else if (type == XmlNodeKeys::WindowType) { return DeserializeWindow(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::WreathType) { - return DeserializeWreath(new wxXmlNode(*node), xlights); + return DeserializeViewObjects(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::ViewObjectsType) { + return DeserializeEffects(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::EffectsType) { + return DeserializeViews(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::ViewsType) { + return DeserializePalettes(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::PalettesType) { + return DeserializeGroups(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::LayoutGroupsType) { + return DeserializePerspectives(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::PerspectivesType) { + return DeserializeSettings(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::SettingsType) { + return DeserializeColors(new wxXmlNode(*node), xlights); + } else if (type == XmlNodeKeys::ColorsType) { + return DeserializeViewPoints(new wxXmlNode(*node), xlights); } throw std::runtime_error("Unknown object type: " + type); @@ -1139,12 +1227,118 @@ struct XmlDeserializingObjectFactory { return model; } + + Model* DeserializeViewObjects(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeEffects(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeViews(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializePalettes(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeGroups(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializePerspectives(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeSettings(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeColors(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } + + Model* DeserializeViewPoints(wxXmlNode* node, xLightsFrame* xlights) { + Model* model; + model = new WreathModel(node, xlights->AllModels, false); + + std::string name = node->GetAttribute("name"); + wxString newname = xlights->AllModels.GenerateModelName(name); + model->SetProperty("name", newname, true); + + return model; + } }; struct XmlSerializer { XmlSerializer() { } + static bool IsXmlSerializerFormat(const wxXmlNode* node) { + if (node->GetAttribute(XmlNodeKeys::TypeAttribute, "") == XmlNodeKeys::ExportedAttribute) { + return true; + } + return false; + } + // Serializes and Saves a single model into an XML document void SerializeAndSaveModel(const BaseObject& object) { wxString name = object.GetModelXml()->GetAttribute("name"); From 044708fc19a4bb63d0217805ae97864aaf63c4c5 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 12 May 2024 15:06:58 -0400 Subject: [PATCH 11/17] XMLSerializer with visitor WIP --- xLights/models/Model.cpp | 27 +++++++++++++++++++++++++++ xLights/models/Model.h | 1 + xLights/models/XmlSerializer.h | 16 +++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/xLights/models/Model.cpp b/xLights/models/Model.cpp index 0e79791f15..0b986531ae 100644 --- a/xLights/models/Model.cpp +++ b/xLights/models/Model.cpp @@ -7571,6 +7571,33 @@ void Model::ExportDimensions(wxFile& f) const } } +std::string Model::GetRulerDim() const { + auto ruler = RulerObject::GetRuler(); + std::string u = ""; + if (ruler != nullptr) { + switch (ruler->GetUnits()) { + case RULER_UNITS_INCHES: + u = "i"; + break; + case RULER_UNITS_FEET: + u = "f"; + break; + case RULER_UNITS_YARDS: + u = "y"; + break; + case RULER_UNITS_MM: + u = "mm"; + break; + case RULER_UNITS_CM: + u = "cm"; + break; + case RULER_UNITS_M: + u = "m"; + break; + } + return u; + } +} void Model::SaveDisplayDimensions() { _savedWidth = GetModelScreenLocation().GetRestorableMWidth(); diff --git a/xLights/models/Model.h b/xLights/models/Model.h index 7675a7430d..a0eeec8978 100644 --- a/xLights/models/Model.h +++ b/xLights/models/Model.h @@ -165,6 +165,7 @@ class Model : public BaseObject void SetBlackTransparency(int t); void ApplyDimensions(const std::string& units, float width, float height, float depth, float& min_x, float& max_x, float& min_y, float& max_y); void ExportDimensions(wxFile& f) const; + std::string GetRulerDim() const; virtual bool AllNodesAllocated() const { return true; } static void ParseFaceInfo(wxXmlNode* fiNode, FaceStateData& faceInfo); diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 02e866b8b9..dbb4261d54 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -137,7 +137,8 @@ namespace XmlNodeKeys { constexpr auto OffsetYAttribute = "OffsetY"; constexpr auto OffsetZAttribute = "OffsetZ"; - // Dimentions Attributes + // Dimensions Attributes + constexpr auto DimNodeName = "dimensions"; constexpr auto DimUnitsAttribute = "units"; constexpr auto DimWidthAttribute = "width"; constexpr auto DimHeightAttribute = "height"; @@ -679,6 +680,18 @@ struct XmlSerializingVisitor : BaseObjectVisitor { } } + void AddDimensions(wxXmlNode* node, const Model* m) { + std::string rdu = m->GetRulerDim(); + if (rdu != "") { + wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::DimNodeName); + xmlNode->AddAttribute(XmlNodeKeys::DimDepthAttribute, std::to_string(m->GetModelScreenLocation().GetRealDepth())); + xmlNode->AddAttribute(XmlNodeKeys::DimHeightAttribute, std::to_string(m->GetModelScreenLocation().GetRealHeight())); + xmlNode->AddAttribute(XmlNodeKeys::DimUnitsAttribute, rdu); + xmlNode->AddAttribute(XmlNodeKeys::DimWidthAttribute, std::to_string(m->GetModelScreenLocation().GetRealWidth())); + node->AddChild(xmlNode); + } + } + //xmlNode->AddAttribute(XmlNodeKeys::#, std::to_string(#())); void AddOtherElements(wxXmlNode* xmlNode, const Model* m) @@ -690,6 +703,7 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddSubmodels(xmlNode, m); AddGroups(xmlNode, m); AddControllerConnection(xmlNode, m); + AddDimensions(xmlNode, m); parentNode->AddChild(xmlNode); } From 45c53c0ab21b268ef8a47b5b2a2d202d336cd99f Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 14 May 2024 23:58:08 -0400 Subject: [PATCH 12/17] XMLSerializer with visitor WIP --- xLights/models/CustomModel.cpp | 110 +++++++++++++++++++++++++++++++-- xLights/models/CustomModel.h | 2 + xLights/models/XmlSerializer.h | 69 ++++++++++++++------- 3 files changed, 155 insertions(+), 26 deletions(-) diff --git a/xLights/models/CustomModel.cpp b/xLights/models/CustomModel.cpp index 16b0da8ef0..aa7b0103f5 100644 --- a/xLights/models/CustomModel.cpp +++ b/xLights/models/CustomModel.cpp @@ -24,7 +24,7 @@ #include "../ExternalHooks.h" #include "outputs/OutputManager.h" #include "../ModelPreview.h" - +#include "XmlSerializer.h" #include CustomModel::CustomModel(wxXmlNode *node, const ModelManager &manager, bool zeroBased) : ModelWithScreenLocation(manager) @@ -294,8 +294,13 @@ void CustomModel::InitModel() static log4cpp::Category& logger_base = log4cpp::Category::getInstance(std::string("log_base")); wxStopWatch sw; - std::string customModel = ModelXml->GetAttribute("CustomModel").ToStdString(); - InitCustomMatrix(customModel); + std::string customModel = ModelXml->GetAttribute("CustomModel2.0"); + if (customModel != "") { + InitCustomMatrix(customModel, true); + } else { + std::string customModel = ModelXml->GetAttribute("CustomModel"); + InitCustomMatrix(customModel); + } //CopyBufCoord2ScreenCoord(); custom_background = ModelXml->GetAttribute("CustomBkgImage").ToStdString(); _strings = wxAtoi(ModelXml->GetAttribute("CustomStrings", "1")); @@ -405,7 +410,8 @@ std::list CustomModel::GetFileReferences() void CustomModel::SetStringStartChannels(bool zeroBased, int NumberOfStrings, int StartChannel, int ChannelsPerString) { - std::string customModel = ModelXml->GetAttribute("CustomModel").ToStdString(); + std::string customModel = ModelXml->GetAttribute("CustomModel2.0"); + if (customModel == "") std::string customModel = ModelXml->GetAttribute("CustomModel").ToStdString(); _strings = wxAtoi(ModelXml->GetAttribute("CustomStrings", "1").ToStdString()); int maxval = GetCustomMaxChannel(customModel); // fix NumberOfStrings @@ -693,6 +699,100 @@ int CustomModel::GetCustomMaxChannel(const std::string& customModel) const return maxval; } +void CustomModel::InitCustomMatrix(const std::string& customModel, const bool& isCompressed) { + + locations.clear(); + std::vector layers; + Split(customModel, '|', layers); + std::vector header; + Split(layers[0], ',', header); + + uint16_t width = wxAtoi(header[2]); + uint16_t height = wxAtoi(header[3]); + uint16_t depth = wxAtoi(header[4]); + std::vector nodemap(wxAtoi(header[1]), -1); + int cpn = -1; + + int32_t firstStartChan = 999999999; + for (auto it : stringStartChan) { + firstStartChan = std::min(it, firstStartChan); + } + + locations = std::vector < std::vector>>(depth, std::vector>(height, std::vector(width, -1))); + + int step = (header[0] == "1" ? 2 : 3); + + for (auto l = 1; l < layers.size(); l++) { + int layer = l - 1; + std::vector cm; + Split(layers[l], ',', cm); + + for (auto n = 0; n < cm.size()/step; n++) { + const int h = wxAtoi(cm[n * step]); + const int w = wxAtoi(cm[n * step + 1]); + if (header[0] == "1") + locations[layer][h][w] = n + 1; + else + locations[layer][h][w] = wxAtoi(cm[n * 3 + 2]); + int idx = locations[layer][h][w]-1; + + // is node already defined in map? + if (nodemap[idx] < 0) { + // unmapped - so add a node + nodemap[idx] = Nodes.size(); + SetNodeCount(1, 0, rgbOrder); // this creates a node of the correct class + Nodes.back()->StringNum = idx; + if (cpn == -1) { + cpn = GetChanCountPerNode(); + } + Nodes.back()->ActChan = firstStartChan + idx * cpn; + if (idx < nodeNames.size() && !nodeNames[idx].empty()) { + Nodes.back()->SetName(nodeNames[idx]); + } else { + Nodes.back()->SetName("Node " + std::to_string(idx + 1)); + } + Nodes.back()->AddBufCoord(layer * ((float)width) + w, ((float)height) - h - 1); + auto& c = Nodes[nodemap[idx]]->Coords.back(); + c.screenX = (float)w - ((float)width) / 2.0f; + c.screenY = ((float)height) - (float)h - 1.0f - ((float)height) / 2.0f; + c.screenZ = depth - (float)layer - 1.0f - depth / 2.0f; + } else { + // mapped - so add a coord to existing node + Nodes[nodemap[idx]]->AddBufCoord(layer * ((float)width) + w, ((float)height) - h - 1); + auto& c = Nodes[nodemap[idx]]->Coords.back(); + c.screenX = (float)w - ((float)width) / 2.0f; + c.screenY = ((float)height) - (float)h - 1.0f - ((float)height) / 2.0f; + c.screenZ = depth - (float)layer - 1.0f - depth / 2.0f; + } + } + } + + for (auto& lyr : locations) { + lyr.resize(height); + for (auto& rw : lyr) { + rw.resize(width, -1); + } + } + for (int x = 0; x < Nodes.size(); x++) { + for (int y = x + 1; y < Nodes.size(); y++) { + if (Nodes[y]->StringNum < Nodes[x]->StringNum) { + Nodes[x].swap(Nodes[y]); + } + } + } + for (int x = 0; x < Nodes.size(); x++) { + if (Nodes[x]->GetName().empty()) { + Nodes[x]->SetName(GetNodeName(Nodes[x]->StringNum)); + } + } + // we have 2 sources of truth for the width, height and depth but we take the parm settings rather than the data + // SetBufferSize(height, width * depth); + SetBufferSize(parm2, parm1 * _depth); + if (screenLocation.RenderDp < 10.0f) { + screenLocation.RenderDp = 10.0f; // give the bounding box a little depth + } +} + void CustomModel::InitCustomMatrix(const std::string& customModel) { locations.clear(); @@ -1176,7 +1276,7 @@ void CustomModel::ImportXlightsModel(wxXmlNode* root, xLightsFrame* xlights, flo xlights->GetOutputModelManager()->AddASAPWork(OutputModelManager::WORK_RGBEFFECTS_CHANGE, "CustomModel::ImportXlightsModel"); xlights->GetOutputModelManager()->AddASAPWork(OutputModelManager::WORK_MODELS_CHANGE_REQUIRING_RERENDER, "CustomModel::ImportXlightsModel"); - } else { + } else if (!XmlSerializer::IsXmlSerializerFormat(root)) { DisplayError("Failure loading custom model file."); } } diff --git a/xLights/models/CustomModel.h b/xLights/models/CustomModel.h index 94a9ed3cd1..ceafc5bde7 100644 --- a/xLights/models/CustomModel.h +++ b/xLights/models/CustomModel.h @@ -81,6 +81,8 @@ class CustomModel : public ModelWithScreenLocation private: int GetCustomMaxChannel(const std::string& customModel) const; void InitCustomMatrix(const std::string& customModel); + void InitCustomMatrix(const std::string& customModel, const bool& isCompressed); + static std::string StartNodeAttrName(int idx) { return wxString::Format(wxT("String%i"), idx + 1).ToStdString(); // a space between "String" and "%i" breaks the start channels listed in Indiv Start Chans diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index dbb4261d54..9354f8a9cb 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -68,7 +68,7 @@ namespace XmlNodeKeys { constexpr auto CZigZagAttribute = "zigZag"; //fix it constexpr auto CustomColorsAttribute = "CustomColors"; constexpr auto TypeAttribute = "type"; - constexpr auto CReverseAttribute = "reverse"; //fix it + constexpr auto CReverseAttribute = "reverse"; //fix it constexpr auto ReverseAttribute = "Reverse"; //fix it // Common Model Attributes @@ -706,7 +706,51 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddDimensions(xmlNode, m); parentNode->AddChild(xmlNode); } - + + void AddCustomModel(wxXmlNode* xmlNode, const CustomModel& m) { + std::vector>> locations = m.GetLocations(); + std::vector> customModel; + std::string type1 = ""; + std::string type2 = ""; + bool hasInfo = false; + uint16_t maxNode = 0; + auto custom_comparator = [](const std::vector& a, const std::vector& b) { return a[2] < b[2]; }; + for (auto l = 0; l < locations.size(); l++) { + type2 += (l > 0 ? "|" : ""); + hasInfo = false; + bool newRow = true; + for (auto h = 0; h < locations[l].size(); h++) { + for (auto w = 0; w < locations[l][h].size(); w++) { + if (locations[l][h][w] != -1) { + type2 += (hasInfo && !newRow ? "," : "") + std::to_string(h) + "," + std::to_string(w) + "," + std::to_string(locations[l][h][w]); + if (locations[l][h][w] > maxNode) maxNode = locations[l][h][w]; + newRow = false; + hasInfo = true; + if (m.IsAllNodesUnique()) { + std::vector row; + row.push_back(h); + row.push_back(w); + row.push_back(locations[l][h][w]); + customModel.push_back(row); + } + } + } + } + } + std::string stats = std::to_string(maxNode) + "," + std::to_string(m.GetCustomWidth()) + "," + std::to_string(m.GetCustomHeight()) + "," + std::to_string(m.GetCustomDepth()); + if (m.IsAllNodesUnique() && locations.size() == 1) { + std::sort(customModel.begin(), customModel.end(), custom_comparator); + if (customModel.back()[2] == customModel.size()) { + for (auto r = 0; r < customModel.size(); r++) + type1 += (r > 0 ? "," : "") + std::to_string(customModel[r][0]) + "," + std::to_string(customModel[r][1]); + xmlNode->AddAttribute("CustomModel2.0", "1," + stats + ",0,0|" + type1); + } else { + xmlNode->AddAttribute("CustomModel2.0", "2," + stats + ",0,0|" + type2); + } + } else { + xmlNode->AddAttribute("CustomModel2.0", "2," + stats + ",0,0|" + type2); + } + } void Visit(const ArchesModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); @@ -781,29 +825,12 @@ struct XmlSerializingVisitor : BaseObjectVisitor { AddCommonModelAttributes(model, xmlNode); AddModelScreenLocationAttributes(model, xmlNode); xmlNode->AddAttribute(XmlNodeKeys::CMDepthAttribute, std::to_string(model.GetCustomDepth())); - xmlNode->AddAttribute(XmlNodeKeys::CustomModelAttribute, model.GetCustomData()); + //xmlNode->AddAttribute(XmlNodeKeys::CustomModelAttribute, model.GetCustomData()); xmlNode->AddAttribute(XmlNodeKeys::BkgImageAttribute, model.GetCustomBackground()); xmlNode->AddAttribute(XmlNodeKeys::BkgLightnessAttribute, std::to_string(model.GetCustomLightness())); - std::vector>> locations = model.GetLocations(); - std::string cm2 = ""; - for (auto l = 0; l < locations.size(); l++) { - for (auto h = 0; h < locations[l].size(); h++) { - for (auto w = 0; w < locations[l][h].size(); w++) { - if (locations.size() == 1) { - if (locations[l][h][w] != -1) - cm2 += std::to_string(h) + "," + std::to_string(w) + "," + std::to_string(locations[l][h][w]) + ","; - } else { - if (locations[l][h][w] != -1) - cm2 += std::to_string(l) + "," + std::to_string(h) + "," + std::to_string(w) + "," + std::to_string(locations[l][h][w]) + ","; - } - } - } - } - xmlNode->AddAttribute("CustomModel2.0", cm2); const Model* m = dynamic_cast(&model); + AddCustomModel(xmlNode, model); AddOtherElements(xmlNode, m); - - } void Visit(const IciclesModel& model) override { wxXmlNode* xmlNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelNodeName); From 95bf596f05c4aef533ae0d7db37d0aa19e67ad07 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 15 May 2024 00:35:44 -0400 Subject: [PATCH 13/17] XMLSerializer with visitor WIP --- xLights/models/XmlSerializer.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 9354f8a9cb..d72dafd9f7 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -1370,15 +1370,7 @@ struct XmlDeserializingObjectFactory { }; struct XmlSerializer { - XmlSerializer() { - } - - static bool IsXmlSerializerFormat(const wxXmlNode* node) { - if (node->GetAttribute(XmlNodeKeys::TypeAttribute, "") == XmlNodeKeys::ExportedAttribute) { - return true; - } - return false; - } + XmlSerializer() {} // Serializes and Saves a single model into an XML document void SerializeAndSaveModel(const BaseObject& object) { @@ -1390,6 +1382,13 @@ struct XmlSerializer { doc.Save(filename); } + static bool IsXmlSerializerFormat(const wxXmlNode* node) { + if (node->GetAttribute(XmlNodeKeys::TypeAttribute, "") == XmlNodeKeys::ExportedAttribute) { + return true; + } + return false; + } + // Serialize a single model into an XML document wxXmlDocument SerializeModel(const BaseObject& object) { wxXmlDocument doc; From 3e84d2a277954ad1bd92581ed72b0901b2af501d Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 15 May 2024 08:55:56 -0400 Subject: [PATCH 14/17] XMLSerializer with visitor WIP --- xLights/models/XmlSerializer.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index d72dafd9f7..57e72caf2c 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -1382,13 +1382,6 @@ struct XmlSerializer { doc.Save(filename); } - static bool IsXmlSerializerFormat(const wxXmlNode* node) { - if (node->GetAttribute(XmlNodeKeys::TypeAttribute, "") == XmlNodeKeys::ExportedAttribute) { - return true; - } - return false; - } - // Serialize a single model into an XML document wxXmlDocument SerializeModel(const BaseObject& object) { wxXmlDocument doc; From 1b9c23d908e53571c348e69f40c0a4c46fd92ab0 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 May 2024 21:48:49 -0400 Subject: [PATCH 15/17] XMLSerializer with visitor WIP --- xLights/ColorManager.h | 2 + xLights/LayoutGroup.h | 1 + xLights/LayoutPanel.cpp | 4 +- xLights/models/XmlSerializer.h | 184 ++++++++++++++++++++++++++++----- xLights/xLightsMain.cpp | 10 ++ xLights/xLightsMain.h | 4 +- 6 files changed, 178 insertions(+), 27 deletions(-) diff --git a/xLights/ColorManager.h b/xLights/ColorManager.h index 58d7d6feca..d76d69a9fa 100644 --- a/xLights/ColorManager.h +++ b/xLights/ColorManager.h @@ -158,6 +158,8 @@ class ColorManager { ColorManager::ColorNames::COLOR_TEXT_UNSELECTED, "TextUnselected", "Unselected Text", xlLIGHT_GREY, ColorManager::ColorCategory::COLOR_CAT_LAYOUT_TAB }, { ColorManager::ColorNames::COLOR_TEXT_HIGHLIGHTED, "TextHighlighted", "Highlighted Text", xlBLUE, ColorManager::ColorCategory::COLOR_CAT_LAYOUT_TAB } }; + std::map GetColors() { return colors; } + std::map GetDefaultColors() { return colors_default; } protected: diff --git a/xLights/LayoutGroup.h b/xLights/LayoutGroup.h index 07c4b48758..f4f7475478 100644 --- a/xLights/LayoutGroup.h +++ b/xLights/LayoutGroup.h @@ -21,6 +21,7 @@ class PreviewPane; class LayoutGroup : public wxObject { public: + LayoutGroup(); LayoutGroup(const std::string & name, xLightsFrame* xl, wxXmlNode *node); virtual ~LayoutGroup(); diff --git a/xLights/LayoutPanel.cpp b/xLights/LayoutPanel.cpp index 5b71aaa2e3..9a1b77d70c 100644 --- a/xLights/LayoutPanel.cpp +++ b/xLights/LayoutPanel.cpp @@ -4952,7 +4952,7 @@ void LayoutPanel::OnPreviewModelPopup(wxCommandEvent& event) return; if (md->SupportsVisitors()) { XmlSerializer serializer; - serializer.SerializeAndSaveModel(*md); + serializer.SerializeAndSaveModel(*md, xlights); } else { md->ExportXlightsModel(); } @@ -7489,7 +7489,7 @@ void LayoutPanel::OnModelsPopup(wxCommandEvent& event) { return; if (md->SupportsVisitors()) { XmlSerializer serializer; - serializer.SerializeAndSaveModel(*md); + serializer.SerializeAndSaveModel(*md, xlights); } else { md->ExportXlightsModel(); } diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 77b34b42da..431373b1fa 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -19,15 +19,19 @@ #include "CandyCaneModel.h" #include "ChannelBlockModel.h" #include "CircleModel.h" +#include "Color.h" #include "CubeModel.h" #include "CustomModel.h" #include "DimmingCurve.h" #include "IciclesModel.h" #include "ImageModel.h" +#include "LayoutGroup.h" #include "MatrixModel.h" +#include "ModelManager.h" #include "Model.h" #include "ModelGroup.h" #include "PolyLineModel.h" +#include "SequenceViewManager.h" #include "SingleLineModel.h" #include "SphereModel.h" #include "SpinnerModel.h" @@ -70,6 +74,7 @@ namespace XmlNodeKeys { constexpr auto TypeAttribute = "type"; constexpr auto CReverseAttribute = "reverse"; //fix it constexpr auto ReverseAttribute = "Reverse"; //fix it + constexpr auto PointDataAttribute = "PointData"; // Common Model Attributes constexpr auto StartSideAttribute = "StartSide"; @@ -94,6 +99,8 @@ namespace XmlNodeKeys { constexpr auto CustomStringsAttribute = "String"; constexpr auto TagColourAttribute = "TagColour"; constexpr auto PixelStyleAttribute = "PixelStyle"; + constexpr auto XLVersionAttribute = "xLightsVersion"; + constexpr auto SettingsAttribute = "settings"; // Common SubModel Attributes @@ -207,7 +214,6 @@ namespace XmlNodeKeys { constexpr auto SmartRemoteTypeAttribute = "SmartRemoteType"; constexpr auto SmartRemoteAttribute = "SmartRemote"; - // Mesh Attributes constexpr auto ObjFileAttribute = "ObjFile"; constexpr auto MeshOnlyAttribute = "MeshOnly"; @@ -264,7 +270,6 @@ namespace XmlNodeKeys { // Poly Line Model constexpr auto NumPointsAttribute = "NumPoints"; - constexpr auto PointDataAttribute = "PointData"; constexpr auto cPointDataAttribute = "cPointData"; constexpr auto IndivSegAttribute = "IndivSegs"; constexpr auto SegsExpandedAttribute = "SegsExpanded"; @@ -304,21 +309,62 @@ namespace XmlNodeKeys { // WIP // constexpr auto Attribute = ""; + //Layout Groups + constexpr auto BackgroundImageAttribute = "backgroundImage"; + constexpr auto BackgroundBrightnessAttribute = "backgroundBrightness"; + constexpr auto BackgroundAlphaAttribute = "backgroundAlpha"; + constexpr auto ScaleImageAttribute = "scaleImage"; + // View_Object + constexpr auto GridLineSpacingAttribute = "GridLineSpacing"; + constexpr auto GridWidthAttribute = "GridWidth"; + constexpr auto GridHeightAttribute = "GridHeight"; + constexpr auto UnitsAttribute = "Units"; + constexpr auto LengthAttribute = "Length"; + constexpr auto TerrainLineAttribute = "TerrianLineSpacing"; //fix spelling in v8 + constexpr auto TerrainWidthAttribute = "TerrianWidth"; //fix spelling in v8 + constexpr auto TerrainDepthAttribute = "TerrianDepth"; //fix spelling in v8 + constexpr auto TerrainBrushAttribute = "TerrianBrushSize"; //fix spelling in v8 + constexpr auto GridColorAttribute = "gridColor"; + constexpr auto HideGridAttribute = "HideGrid"; + constexpr auto HideImageAttribute = "HideImage"; + constexpr auto ObjAttribute = "ObjFile"; + + //Settings + constexpr auto ValueAttribute = "value"; + + //Colors + //Already does it in ColorManager.cpp ColorManager::Save() + constexpr auto RedAttribute = "Red"; + constexpr auto GreenAttribute = "Green"; + constexpr auto BlueAttribute = "Blue"; // Effect Version + constexpr auto VersionAttribute = "version"; - // Effect Group - - // View + // Previews + constexpr auto ModelsAttribute = "models"; // Group - already done // Perspectives - - // Settings + constexpr auto CurrentAttribute = "current"; // ViewPoint + constexpr auto posXAttribute = "posX"; + constexpr auto posYAttribute = "posY"; + constexpr auto posZAttribute = "posZ"; + constexpr auto angleXAttribute = "angleX"; + constexpr auto angleYAttribute = "angleY"; + constexpr auto angleZAttribute = "angleZ"; + constexpr auto distanceAttribute = "distance"; + constexpr auto zoomAttribute = "zoom"; + constexpr auto panXAttribute = "panx"; + constexpr auto panYAttribute = "pany"; + constexpr auto panZAttribute = "panz"; + constexpr auto zoomXAttribute = "zoom_corrx"; + constexpr auto zoomYAttribute = "zoom_corry"; + constexpr auto is3DAttribute = "is_ed"; // Model Types constexpr auto ArchesType = "Arches"; @@ -340,7 +386,7 @@ namespace XmlNodeKeys { constexpr auto WindowType = "Window Frame"; constexpr auto WreathType = "Wreath"; - //Extra Objects + //Extra Types constexpr auto ViewObjectsType = "view_objects"; constexpr auto EffectsType = "effects"; constexpr auto ViewsType = "views"; @@ -1041,7 +1087,7 @@ struct XmlDeserializingObjectFactory { } else if (type == XmlNodeKeys::WindowType) { return DeserializeWindow(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::WreathType) { - return DeserializeViewObjects(new wxXmlNode(*node), xlights); + return DeserializeWreath(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::ViewObjectsType) { return DeserializeEffects(new wxXmlNode(*node), xlights); } else if (type == XmlNodeKeys::EffectsType) { @@ -1269,17 +1315,6 @@ struct XmlDeserializingObjectFactory { return model; } - Model* DeserializeViewObjects(wxXmlNode* node, xLightsFrame* xlights) { - Model* model; - model = new WreathModel(node, xlights->AllModels, false); - - std::string name = node->GetAttribute("name"); - wxString newname = xlights->AllModels.GenerateModelName(name); - model->SetProperty("name", newname, true); - - return model; - } - Model* DeserializeEffects(wxXmlNode* node, xLightsFrame* xlights) { Model* model; model = new WreathModel(node, xlights->AllModels, false); @@ -1381,17 +1416,18 @@ struct XmlSerializer { } // Serializes and Saves a single model into an XML document - void SerializeAndSaveModel(const BaseObject& object) { + void SerializeAndSaveModel(const BaseObject& object, xLightsFrame* xlights) { wxString name = object.GetModelXml()->GetAttribute("name"); + wxString filename = wxFileSelector(_("Choose output file"), wxEmptyString, name, wxEmptyString, "Custom Model files (*.xmodel)|*.xmodel", wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (filename.IsEmpty()) return; - wxXmlDocument doc = SerializeModel(object); + wxXmlDocument doc = SerializeModel(object, xlights); doc.Save(filename); } // Serialize a single model into an XML document - wxXmlDocument SerializeModel(const BaseObject& object) { + wxXmlDocument SerializeModel(const BaseObject& object, xLightsFrame* xlights) { wxXmlDocument doc; wxXmlNode* docNode = new wxXmlNode(wxXML_ELEMENT_NODE, XmlNodeKeys::ModelsNodeName); @@ -1403,6 +1439,11 @@ struct XmlSerializer { doc.SetRoot(docNode); + //DeserializeLayoutGroupsObject(docNode, xlights); + //DeserializeViewsObject(docNode, xlights); + //DeserializeColorsObject(docNode, xlights); + //DeserializePerspectivesObject(docNode, xlights); + //DeserializeSettingsObject(docNode, xlights); return doc; } @@ -1427,4 +1468,101 @@ struct XmlSerializer { return model; } + + void DeserializeViewsObject(wxXmlNode* node, xLightsFrame* xlights) { + wxXmlNode* viewsNode = new wxXmlNode(wxXML_ELEMENT_NODE, "views"); + SequenceViewManager* seqViewMgr = xlights->GetViewsManager(); + std::list views = seqViewMgr->GetViews(); + for (SequenceView* view : views) { + std::string name = view->GetName(); + if (name != "Master View") { + wxXmlNode* viewChild = new wxXmlNode(wxXML_ELEMENT_NODE, "view"); + viewChild->AddAttribute("name", name); + viewChild->AddAttribute(XmlNodeKeys::ModelsAttribute, view->GetModelsString()); + viewsNode->AddChild(viewChild); + } + } + node->AddChild(viewsNode); + } + + void DeserializeColorsObject(wxXmlNode* node, xLightsFrame* xlights) { + wxXmlNode* colorsNode = new wxXmlNode(wxXML_ELEMENT_NODE, "colors"); + ColorManager* colorMgr = new ColorManager(xlights); + std::map colors = colorMgr->GetColors(); + for (const auto& c : colors) { + wxXmlNode* colorChild = new wxXmlNode(wxXML_ELEMENT_NODE, c.first); + colorChild->AddAttribute(XmlNodeKeys::RedAttribute, std::to_string(c.second.red)); + colorChild->AddAttribute(XmlNodeKeys::GreenAttribute, std::to_string(c.second.green)); + colorChild->AddAttribute(XmlNodeKeys::BlueAttribute, std::to_string(c.second.blue)); + colorsNode->AddChild(colorChild); + } + node->AddChild(colorsNode); + } + + void DeserializeLayoutGroupsObject(wxXmlNode* node, xLightsFrame* xlights) { + std::vector layoutGroups = xlights->LayoutGroups; + wxXmlNode* lgNode = new wxXmlNode(wxXML_ELEMENT_NODE, "layoutGroups"); + for (LayoutGroup* lg : layoutGroups) { + wxXmlNode* lgChild = new wxXmlNode(wxXML_ELEMENT_NODE, "layoutGroup"); + lgChild->AddAttribute("name", lg->GetName()); + lgChild->AddAttribute(XmlNodeKeys::BackgroundImageAttribute, lg->GetBackgroundImage()); + lgChild->AddAttribute(XmlNodeKeys::BackgroundBrightnessAttribute, std::to_string(lg->GetBackgroundBrightness())); + lgChild->AddAttribute(XmlNodeKeys::BackgroundAlphaAttribute, std::to_string(lg->GetBackgroundAlpha())); + lgChild->AddAttribute(XmlNodeKeys::ScaleImageAttribute, std::to_string(lg->GetBackgroundScaled())); + lgNode->AddChild(lgChild); + } + node->AddChild(lgNode); + } + + void DeserializePerspectivesObject(wxXmlNode* node, xLightsFrame* xlights) { + std::list perspectives = xlights->GetPerspectives(); + wxXmlNode* perspectivesNode = new wxXmlNode(wxXML_ELEMENT_NODE, "perspectives"); + for (std::string p : perspectives) { + wxXmlNode* pChild = new wxXmlNode(wxXML_ELEMENT_NODE, "perspective"); + pChild->AddAttribute("name", p); + perspectivesNode->AddChild(pChild); + } + node->AddChild(perspectivesNode); + } + + void DeserializeSettingsObject(wxXmlNode* node, xLightsFrame* xlights) { + wxXmlNode* settings = new wxXmlNode(wxXML_ELEMENT_NODE, "settings"); + wxXmlNode* scaleimage = new wxXmlNode(wxXML_ELEMENT_NODE, "scaleImage"); + scaleimage->AddAttribute("value", std::to_string(xlights->GetDefaultPreviewBackgroundScaled())); + settings->AddChild(scaleimage); + wxXmlNode* bkgimage = new wxXmlNode(wxXML_ELEMENT_NODE, "backgroundImage"); + bkgimage->AddAttribute("value", "tbd"); + settings->AddChild(bkgimage); + wxXmlNode* bkgbright = new wxXmlNode(wxXML_ELEMENT_NODE, "backgroundBrightness"); + bkgbright->AddAttribute("value", std::to_string(xlights->GetDefaultPreviewBackgroundBrightness())); + settings->AddChild(bkgbright); + wxXmlNode* bkgalpha = new wxXmlNode(wxXML_ELEMENT_NODE, "backgroundAlpha"); + bkgalpha->AddAttribute("value", std::to_string(xlights->GetDefaultPreviewBackgroundAlpha())); + settings->AddChild(bkgalpha); + wxXmlNode* boundbox = new wxXmlNode(wxXML_ELEMENT_NODE, "Display2DBoundingBox"); + boundbox->AddAttribute("value", std::to_string(xlights->GetDisplay2DBoundingBox())); + settings->AddChild(boundbox); + wxXmlNode* grid = new wxXmlNode(wxXML_ELEMENT_NODE, "Display2DGrid"); + grid->AddAttribute("value", std::to_string(xlights->GetDisplay2DGrid())); + settings->AddChild(grid); + wxXmlNode* gridspace = new wxXmlNode(wxXML_ELEMENT_NODE, "Display2DGridSpacing"); + gridspace->AddAttribute("value", std::to_string(xlights->GetDisplay2DGridSpacing())); + settings->AddChild(gridspace); + wxXmlNode* center0 = new wxXmlNode(wxXML_ELEMENT_NODE, "Display2DCenter0"); + center0->AddAttribute("value", std::to_string(xlights->GetDisplay2DCenter0())); + settings->AddChild(center0); + wxXmlNode* laygrp = new wxXmlNode(wxXML_ELEMENT_NODE, "storedLayourGroup"); + laygrp->AddAttribute("value", xlights->GetStoredLayoutGroup()); + settings->AddChild(laygrp); + wxXmlNode* layout3d = new wxXmlNode(wxXML_ELEMENT_NODE, "LayoutMode3D"); + layout3d->AddAttribute("value", "tbd"); + settings->AddChild(layout3d); + wxXmlNode* previewW = new wxXmlNode(wxXML_ELEMENT_NODE, "previewWidth"); + previewW->AddAttribute("value", std::to_string(0)); + settings->AddChild(previewW); + wxXmlNode* previewH = new wxXmlNode(wxXML_ELEMENT_NODE, "previewHeight"); + previewH->AddAttribute("value", std::to_string(0)); + settings->AddChild(previewH); + node->AddChild(settings); + } }; diff --git a/xLights/xLightsMain.cpp b/xLights/xLightsMain.cpp index 0d1d8de675..8c8ec552e1 100644 --- a/xLights/xLightsMain.cpp +++ b/xLights/xLightsMain.cpp @@ -10282,3 +10282,13 @@ void xLightsFrame::UpdateFromBaseShowFolder(bool prompt) DoAllWork(); } + +std::list xLightsFrame::GetPerspectives() { + std::list perspectives; + for (wxXmlNode* e = PerspectivesNode->GetChildren(); e != NULL; e = e->GetNext()) { + if (e->GetName() == "perspective") + perspectives.push_back(e->GetAttribute("name")); + + } + return perspectives; +} \ No newline at end of file diff --git a/xLights/xLightsMain.h b/xLights/xLightsMain.h index 8aff3bcaf0..0ccd76ef29 100644 --- a/xLights/xLightsMain.h +++ b/xLights/xLightsMain.h @@ -1881,5 +1881,5 @@ private : void DoPlaySequence(); void RecalcModels(); std::string GetUniqueTimingName(const std::string& baseName); -}; - + std::list GetPerspectives(); +}; \ No newline at end of file From 86021829acc8d91cce21646aa49fb7c88c83097e Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 May 2024 15:40:02 -0400 Subject: [PATCH 16/17] XMLSerializer with visitor WIP --- xLights/models/TerrianObject.cpp | 5 +++ xLights/models/TerrianObject.h | 23 ++++++++++++++ xLights/models/XmlSerializer.h | 52 ++++++++++++++++++++++++++------ 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/xLights/models/TerrianObject.cpp b/xLights/models/TerrianObject.cpp index 0ad2282126..4fe72c5a63 100644 --- a/xLights/models/TerrianObject.cpp +++ b/xLights/models/TerrianObject.cpp @@ -419,3 +419,8 @@ bool TerrianObject::Draw(ModelPreview* preview, xlGraphicsContext *ctx, xlGraphi } return true; } + +std::string TerrianObject::GetAttribute(std::string attribute) { + if (ModelXml->HasAttribute(attribute)) return ModelXml->GetAttribute(attribute); + return ""; +} diff --git a/xLights/models/TerrianObject.h b/xLights/models/TerrianObject.h index df3a8edd2f..ab955dae04 100644 --- a/xLights/models/TerrianObject.h +++ b/xLights/models/TerrianObject.h @@ -33,6 +33,29 @@ class TerrianObject : public ObjectWithScreenLocation virtual bool Draw(ModelPreview* preview, xlGraphicsContext *ctx, xlGraphicsProgram *solid, xlGraphicsProgram *transparent, bool allowSelected = false) override; + // Getter methods for private members + const std::string& getImageFile() const { return _imageFile; } + int getSpacing() const { return spacing; } + const xlColor& getGridColor() const { return gridColor; } + int getWidth() const { return width; } + int getHeight() const { return height; } + int getDepth() const { return depth; } + int getNumPointsWide() const { return num_points_wide; } + int getNumPointsDeep() const { return num_points_deep; } + int getNumPoints() const { return num_points; } + bool isEditTerrian() const { return editTerrian; } + bool isHideImage() const { return hide_image; } + bool isHideGrid() const { return hide_grid; } + int getBrushSize() const { return brush_size; } + int getImgWidth() const { return img_width; } + int getImgHeight() const { return img_height; } + int getTransparency() const { return transparency; } + float getBrightness() const { return brightness; } + std::string getPointData() const { + return std::to_string(num_points) + "," + std::to_string(num_points_deep) + ",0.00," + std::to_string(num_points_wide); + }; + std::string GetAttribute(const std::string); + protected: private: diff --git a/xLights/models/XmlSerializer.h b/xLights/models/XmlSerializer.h index 431373b1fa..95ef3ef329 100644 --- a/xLights/models/XmlSerializer.h +++ b/xLights/models/XmlSerializer.h @@ -23,20 +23,24 @@ #include "CubeModel.h" #include "CustomModel.h" #include "DimmingCurve.h" +#include "GridlinesObject.h" #include "IciclesModel.h" #include "ImageModel.h" #include "LayoutGroup.h" #include "MatrixModel.h" +#include "MeshObject.h" #include "ModelManager.h" #include "Model.h" #include "ModelGroup.h" #include "PolyLineModel.h" +#include "RulerObject.h" #include "SequenceViewManager.h" #include "SingleLineModel.h" #include "SphereModel.h" #include "SpinnerModel.h" #include "StarModel.h" #include "SubModel.h" +#include "TerrianObject.h" #include "ThreePointScreenLocation.h" #include "TreeModel.h" #include "ViewObjectManager.h" @@ -1405,10 +1409,10 @@ struct XmlDeserializingObjectFactory { }; struct XmlSerializer { - XmlSerializer() {} + XmlSerializer() { + } - static bool IsXmlSerializerFormat(const wxXmlNode *node) - { + static bool IsXmlSerializerFormat(const wxXmlNode* node) { if (node->GetAttribute(XmlNodeKeys::TypeAttribute, "") == XmlNodeKeys::ExportedAttribute) { return true; } @@ -1418,7 +1422,7 @@ struct XmlSerializer { // Serializes and Saves a single model into an XML document void SerializeAndSaveModel(const BaseObject& object, xLightsFrame* xlights) { wxString name = object.GetModelXml()->GetAttribute("name"); - + wxString filename = wxFileSelector(_("Choose output file"), wxEmptyString, name, wxEmptyString, "Custom Model files (*.xmodel)|*.xmodel", wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (filename.IsEmpty()) return; @@ -1439,11 +1443,12 @@ struct XmlSerializer { doc.SetRoot(docNode); - //DeserializeLayoutGroupsObject(docNode, xlights); - //DeserializeViewsObject(docNode, xlights); - //DeserializeColorsObject(docNode, xlights); - //DeserializePerspectivesObject(docNode, xlights); - //DeserializeSettingsObject(docNode, xlights); + DeserializeLayoutGroupsObject(docNode, xlights); + DeserializeViewsObject(docNode, xlights); + DeserializeColorsObject(docNode, xlights); + DeserializePerspectivesObject(docNode, xlights); + DeserializeSettingsObject(docNode, xlights); + Deserialize3dObjects(docNode, xlights); return doc; } @@ -1565,4 +1570,33 @@ struct XmlSerializer { settings->AddChild(previewH); node->AddChild(settings); } + + void Deserialize3dObjects(wxXmlNode* node, xLightsFrame* xlights){ + wxXmlNode* settings = new wxXmlNode(wxXML_ELEMENT_NODE, "view_objects"); + wxXmlNode* terrain = new wxXmlNode(wxXML_ELEMENT_NODE, "view_object"); + const ViewObjectManager* om = new ViewObjectManager(xlights); + //std::map vo = om->GetViewObjects(); + //ViewObject* t0 = om->GetViewObject("Terrain"); + //BaseObject* b0 = om->GetObject("Mesh"); + TerrianObject* t = new TerrianObject(node, *om); + //OutputManager* om0 = new OutputManager(); + //ModelManager* mm = new ModelManager(om0, xlights); + //std::map gm = mm->GetModels(); + + terrain->AddAttribute(XmlNodeKeys::ImageAttribute, t->GetAttribute("Image")); + terrain->AddAttribute(XmlNodeKeys::BrightnessAttribute, t->GetAttribute("Brightness")); + terrain->AddAttribute(XmlNodeKeys::TransparencyAttribute, std::to_string(t->getTransparency())); + terrain->AddAttribute(XmlNodeKeys::TerrainLineAttribute, std::to_string(t->getSpacing())); + terrain->AddAttribute(XmlNodeKeys::TerrainWidthAttribute, std::to_string(t->getWidth())); + terrain->AddAttribute(XmlNodeKeys::TerrainDepthAttribute, std::to_string(t->getDepth())); + terrain->AddAttribute(XmlNodeKeys::TerrainBrushAttribute, t->GetAttribute("TerrianBrushSize")); + terrain->AddAttribute(XmlNodeKeys::GridColorAttribute, t->getGridColor()); + terrain->AddAttribute(XmlNodeKeys::HideGridAttribute, std::to_string(t->isHideGrid())); + terrain->AddAttribute(XmlNodeKeys::HideImageAttribute, std::to_string(t->isHideImage())); + terrain->AddAttribute(XmlNodeKeys::PointDataAttribute, t->getPointData()); + + settings->AddChild(terrain); + + node->AddChild(settings); + }; }; From 95b7b68a3f5b5be6590ce16d62b943a896d2e0bb Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 May 2024 19:20:03 -0400 Subject: [PATCH 17/17] XMLSerializer with visitor WIP --- xLights/CustomModelDialog.cpp | 61 +++++++++++++++++++++++----------- xLights/models/CustomModel.cpp | 8 +++-- xLights/models/CustomModel.h | 2 ++ 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/xLights/CustomModelDialog.cpp b/xLights/CustomModelDialog.cpp index b260275930..fde1a524d7 100644 --- a/xLights/CustomModelDialog.cpp +++ b/xLights/CustomModelDialog.cpp @@ -48,6 +48,7 @@ #include "outputs/TwinklyOutput.h" #include "Discovery.h" #include "outputs/OutputManager.h" +#include "string.h" //(*IdInit(CustomModelDialog) const long CustomModelDialog::ID_SPINCTRL1 = wxNewId(); @@ -586,6 +587,7 @@ void CustomModelDialog::Setup(CustomModel* m) lightness = m->GetCustomLightness(); SliderCustomLightness->SetValue(lightness); std::string data = m->GetCustomData(); + bool _hasCM2 = m->hasCM2(); if (background_image != "" && FileExists(background_image)) { bkg_image = new wxImage(background_image); @@ -605,29 +607,50 @@ void CustomModelDialog::Setup(CustomModel* m) } } else { - wxArrayString layers = wxSplit(data, '|'); - for (auto layer = 0; layer < layers.size(); layer++) { - AddPage(); - //ResizeCustomGrid(); - auto grid = GetLayerGrid(layer); - wxArrayString rows = wxSplit(layers[layer], ';'); - //grid->AppendRows(rows.size() - 1); - - for (auto row = 0; row < rows.size(); row++) { - wxArrayString cols = wxSplit(rows[row], ','); - //if (row == 0) { - // grid->AppendCols(cols.size() - 1); - //} - for (auto col = 0; col < cols.size(); col++) { - wxString value = cols[col]; - if (!value.IsEmpty() && value != "0") { - grid->SetCellValue(row, col, value); + if (_hasCM2) { + wxArrayString layers = wxSplit(data, '|'); + wxArrayString ctrllayers = wxSplit(layers[0], ','); + int type = std::stoi(ctrllayers[0].ToStdString()); + int node = 1; + int step = (type == 1 ? 2 : 3); + for (auto layer = 1; layer < layers.size(); layer++) { + AddPage(); + // ResizeCustomGrid(); + auto grid = GetLayerGrid(layer-1); + wxArrayString data = wxSplit(layers[layer], ','); + for (auto d = 0; d < data.size();d+=step){ + if (type == 1) { + grid->SetCellValue(std::stoi(data[d].ToStdString()), std::stoi(data[d + 1].ToStdString()), std::to_string(node)); + node++; + } else { + grid->SetCellValue(std::stoi(data[d].ToStdString()), std::stoi(data[d + 1].ToStdString()), data[d + 2]); } } + + wxFont font = grid->GetDefaultCellFont(); + SetGridSizeForFont(font); } + } else { + wxArrayString layers = wxSplit(data, '|'); + for (auto layer = 0; layer < layers.size(); layer++) { + AddPage(); + // ResizeCustomGrid(); + auto grid = GetLayerGrid(layer); + wxArrayString rows = wxSplit(layers[layer], ';'); + + for (auto row = 0; row < rows.size(); row++) { + wxArrayString cols = wxSplit(rows[row], ','); + for (auto col = 0; col < cols.size(); col++) { + wxString value = cols[col]; + if (!value.IsEmpty() && value != "0") { + grid->SetCellValue(row, col, value); + } + } + } - wxFont font = grid->GetDefaultCellFont(); - SetGridSizeForFont(font); + wxFont font = grid->GetDefaultCellFont(); + SetGridSizeForFont(font); + } } } diff --git a/xLights/models/CustomModel.cpp b/xLights/models/CustomModel.cpp index aa7b0103f5..f051452854 100644 --- a/xLights/models/CustomModel.cpp +++ b/xLights/models/CustomModel.cpp @@ -296,6 +296,7 @@ void CustomModel::InitModel() std::string customModel = ModelXml->GetAttribute("CustomModel2.0"); if (customModel != "") { + _hasCM2 = true; InitCustomMatrix(customModel, true); } else { std::string customModel = ModelXml->GetAttribute("CustomModel"); @@ -339,9 +340,10 @@ void CustomModel::SetCustomDepth(long d) SetFromXml(ModelXml, zeroBased); } -std::string CustomModel::GetCustomData() const -{ - return ModelXml->GetAttribute("CustomModel").ToStdString(); +std::string CustomModel::GetCustomData() const { + std::string cm2 = ModelXml->GetAttribute("CustomModel2.0").ToStdString(); + _hasCM2 == (cm2 != ""); + return (cm2 != "" ? cm2 : ModelXml->GetAttribute("CustomModel").ToStdString()); } void CustomModel::SetCustomData(const std::string& data) diff --git a/xLights/models/CustomModel.h b/xLights/models/CustomModel.h index ceafc5bde7..c9290f071c 100644 --- a/xLights/models/CustomModel.h +++ b/xLights/models/CustomModel.h @@ -73,6 +73,7 @@ class CustomModel : public ModelWithScreenLocation virtual bool SupportsVisitors() override { return true; } void Accept(BaseObjectVisitor& visitor) const override { return visitor.Visit(*this); } + bool hasCM2() const { return _hasCM2; } protected: virtual void InitModel() override; @@ -95,4 +96,5 @@ class CustomModel : public ModelWithScreenLocation int _strings; std::vector stringStartNodes; std::vector>> locations; + bool _hasCM2 = false; };