From 9fe7ff969047df565bae6b39045b6fb52fcf8b50 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 8 Dec 2012 23:27:59 +0100 Subject: [PATCH] added mandatory ID check stage --- apps/opencs/CMakeLists.txt | 2 ++ apps/opencs/model/doc/document.cpp | 1 + apps/opencs/model/doc/document.hpp | 5 ++- apps/opencs/model/tools/mandatoryid.cpp | 21 +++++++++++ apps/opencs/model/tools/mandatoryid.hpp | 38 ++++++++++++++++++++ apps/opencs/model/tools/operation.cpp | 4 +-- apps/opencs/model/tools/stage.hpp | 12 +++---- apps/opencs/model/tools/tools.cpp | 19 +++++++++- apps/opencs/model/tools/tools.hpp | 8 ++++- apps/opencs/model/world/universalid.cpp | 48 ++++++++++++++++++++++++- apps/opencs/model/world/universalid.hpp | 2 ++ 11 files changed, 148 insertions(+), 12 deletions(-) create mode 100644 apps/opencs/model/tools/mandatoryid.cpp create mode 100644 apps/opencs/model/tools/mandatoryid.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 381ce51cf..bad1e1376 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -8,6 +8,7 @@ set (OPENCS_SRC model/world/commands.cpp model/world/idtableproxymodel.cpp model/world/record.cpp model/tools/tools.cpp model/tools/operation.cpp model/tools/stage.cpp model/tools/verifier.cpp + model/tools/mandatoryid.cpp view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp @@ -24,6 +25,7 @@ set (OPENCS_HDR model/world/commands.hpp model/tools/tools.hpp model/tools/operation.hpp model/tools/stage.hpp model/tools/verifier.hpp + model/tools/mandatoryid.hpp view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index d8ad5ff01..f03344e08 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2,6 +2,7 @@ #include "document.hpp" CSMDoc::Document::Document (const std::string& name) +: mTools (mData) { mName = name; ///< \todo replace with ESX list diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 40f8c0ea1..f9d0a232c 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -22,10 +22,13 @@ namespace CSMDoc private: std::string mName; ///< \todo replace name with ESX list - QUndoStack mUndoStack; CSMWorld::Data mData; CSMTools::Tools mTools; + // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is + // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. + QUndoStack mUndoStack; + int mSaveCount; ///< dummy implementation -> remove when proper save is implemented. QTimer mSaveTimer; ///< dummy implementation -> remove when proper save is implemented. diff --git a/apps/opencs/model/tools/mandatoryid.cpp b/apps/opencs/model/tools/mandatoryid.cpp new file mode 100644 index 000000000..87ac77e67 --- /dev/null +++ b/apps/opencs/model/tools/mandatoryid.cpp @@ -0,0 +1,21 @@ + +#include "mandatoryid.hpp" + +#include "../world/idcollection.hpp" + +CSMTools::MandatoryIdStage::MandatoryIdStage (const CSMWorld::IdCollectionBase& idCollection, + const CSMWorld::UniversalId& collectionId, const std::vector& ids) +: mIdCollection (idCollection), mCollectionId (collectionId), mIds (ids) +{} + +int CSMTools::MandatoryIdStage::setup() +{ + return mIds.size(); +} + +void CSMTools::MandatoryIdStage::perform (int stage, std::vector& messages) +{ + if (mIdCollection.searchId (mIds.at (stage))==-1 || + mIdCollection.getRecord (mIds.at (stage)).isDeleted()) + messages.push_back (mCollectionId.toString() + " Missing mandatory record: " + mIds.at (stage)); +} \ No newline at end of file diff --git a/apps/opencs/model/tools/mandatoryid.hpp b/apps/opencs/model/tools/mandatoryid.hpp new file mode 100644 index 000000000..14fcec204 --- /dev/null +++ b/apps/opencs/model/tools/mandatoryid.hpp @@ -0,0 +1,38 @@ +#ifndef CSM_TOOLS_MANDATORYID_H +#define CSM_TOOLS_MANDATORYID_H + +#include +#include + +#include "../world/universalid.hpp" + +#include "stage.hpp" + +namespace CSMWorld +{ + class IdCollectionBase; +} + +namespace CSMTools +{ + /// \brief Verify stage: make sure that records with specific IDs exist. + class MandatoryIdStage : public Stage + { + const CSMWorld::IdCollectionBase& mIdCollection; + CSMWorld::UniversalId mCollectionId; + std::vector mIds; + + public: + + MandatoryIdStage (const CSMWorld::IdCollectionBase& idCollection, const CSMWorld::UniversalId& collectionId, + const std::vector& ids); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this tage will be appended to \a messages. + }; +} + +#endif diff --git a/apps/opencs/model/tools/operation.cpp b/apps/opencs/model/tools/operation.cpp index b68f79ca4..71761cdae 100644 --- a/apps/opencs/model/tools/operation.cpp +++ b/apps/opencs/model/tools/operation.cpp @@ -19,8 +19,8 @@ void CSMTools::Operation::prepareStages() for (std::vector >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter) { - iter->second = mTotalSteps; - mTotalSteps += iter->first->setup(); + iter->second = iter->first->setup(); + mTotalSteps += iter->second; } } diff --git a/apps/opencs/model/tools/stage.hpp b/apps/opencs/model/tools/stage.hpp index 1ad61960a..3020936f3 100644 --- a/apps/opencs/model/tools/stage.hpp +++ b/apps/opencs/model/tools/stage.hpp @@ -8,15 +8,15 @@ namespace CSMTools { class Stage { - public: + public: - virtual ~Stage(); + virtual ~Stage(); - virtual int setup() = 0; - ///< \return number of steps + virtual int setup() = 0; + ///< \return number of steps - virtual void perform (int stage, std::vector& messages) = 0; - ///< Messages resulting from this tage will be appended to \a messages. + virtual void perform (int stage, std::vector& messages) = 0; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 8293b7291..a3cdb7822 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -7,6 +7,10 @@ #include "../doc/state.hpp" +#include "../world/data.hpp" + +#include "mandatoryid.hpp" + CSMTools::Operation *CSMTools::Tools::get (int type) { switch (type) @@ -32,12 +36,25 @@ CSMTools::Verifier *CSMTools::Tools::getVerifier() connect (mVerifier, SIGNAL (finished()), this, SLOT (verifierDone())); connect (mVerifier, SIGNAL (reportMessage (const QString&, int)), this, SLOT (verifierMessage (const QString&, int))); + + std::vector mandatoryIds; // I want C++11, damn it! + mandatoryIds.push_back ("Day"); + mandatoryIds.push_back ("DaysPassed"); + mandatoryIds.push_back ("GameHour"); + mandatoryIds.push_back ("Month"); + mandatoryIds.push_back ("PCRace"); + mandatoryIds.push_back ("PCVampire"); + mandatoryIds.push_back ("PCWerewolf"); + mandatoryIds.push_back ("PCYear"); + + mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(), + CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); } return mVerifier; } -CSMTools::Tools::Tools() : mVerifier (0) +CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0) { } diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 04140bb91..da49fd8b8 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -3,6 +3,11 @@ #include +namespace CSMWorld +{ + class Data; +} + namespace CSMTools { class Verifier; @@ -12,6 +17,7 @@ namespace CSMTools { Q_OBJECT + CSMWorld::Data& mData; Verifier *mVerifier; // not implemented @@ -28,7 +34,7 @@ namespace CSMTools public: - Tools(); + Tools (CSMWorld::Data& data); virtual ~Tools(); diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index e2d8d1ffb..229779f5a 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -35,6 +35,52 @@ namespace }; } +CSMWorld::UniversalId::UniversalId (const std::string& universalId) +{ + std::string::size_type index = universalId.find (':'); + + if (index!=std::string::npos) + { + std::string type = universalId.substr (0, index); + + for (int i=0; sNoArg[i].mName; ++i) + if (type==sNoArg[i].mName) + { + mArgumentType = ArgumentType_None; + mType = sNoArg[i].mType; + mClass = sNoArg[i].mClass; + return; + } + + for (int i=0; sIdArg[i].mName; ++i) + if (type==sIdArg[i].mName) + { + mArgumentType = ArgumentType_Id; + mType = sIdArg[i].mType; + mClass = sIdArg[i].mClass; + mId = universalId.substr (0, index); + return; + } + + for (int i=0; sIndexArg[i].mName; ++i) + if (type==sIndexArg[i].mName) + { + mArgumentType = ArgumentType_Index; + mType = sIndexArg[i].mType; + mClass = sIndexArg[i].mClass; + + std::istringstream stream (universalId.substr (0, index)); + + if (stream >> mIndex) + return; + + break; + } + } + + throw std::runtime_error ("invalid UniversalId: " + universalId); +} + CSMWorld::UniversalId::UniversalId (Type type) : mArgumentType (ArgumentType_None), mType (type), mIndex (0) { for (int i=0; sNoArg[i].mName; ++i) @@ -151,7 +197,7 @@ std::string CSMWorld::UniversalId::toString() const { std::ostringstream stream; - stream << getTypeName(); + stream << getTypeName() << ":"; switch (mArgumentType) { diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 6dc0eda1e..7b630ebc7 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -44,6 +44,8 @@ namespace CSMWorld public: + UniversalId (const std::string& universalId); + UniversalId (Type type = Type_None); ///< Using a type for a non-argument-less UniversalId will throw an exception.