mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Metadata editor now saves userlist on 'OK' exit, fixed linker errors.
This commit is contained in:
+12
-23
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
|
||||
#include "editor.h"
|
||||
#include "../parsers.h"
|
||||
|
||||
#include <wx/statline.h>
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@@ -65,7 +65,7 @@ wxString State[2] = {
|
||||
translate("Remove")
|
||||
};
|
||||
|
||||
Editor::Editor(wxWindow *parent, const wxString& title) : wxFrame(parent, wxID_ANY, title) {
|
||||
Editor::Editor(wxWindow *parent, const wxString& title, const boss::Game& game, const std::vector<boss::Plugin>& basePlugins, std::vector<boss::Plugin>& editedPlugins, bool showRecalcButton) : wxFrame(parent, wxID_ANY, title), _game(game), _basePlugins(basePlugins), _editedPlugins(editedPlugins) {
|
||||
|
||||
//Initialise child windows.
|
||||
listBook = new wxNotebook(this, BOOK_Lists);
|
||||
@@ -189,33 +189,22 @@ Editor::Editor(wxWindow *parent, const wxString& title) : wxFrame(parent, wxID_A
|
||||
mainBox->Add(hbox6, 0, wxALIGN_RIGHT);
|
||||
|
||||
bigBox->Add(mainBox, 2, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 10);
|
||||
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
SetIcon(wxIconLocation("BOSS.exe"));
|
||||
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void Editor::SetList(const std::vector<boss::Plugin>& basePlugins, const std::vector<boss::Plugin>& editedPlugins) {
|
||||
_basePlugins = basePlugins;
|
||||
_editedPlugins = editedPlugins;
|
||||
|
||||
//Fill pluginList with the contents of basePlugins.
|
||||
for (int i=0, max=_basePlugins.size(); i < max; ++i) {
|
||||
pluginList->InsertItem(i, FromUTF8(_basePlugins[i].Name()));
|
||||
}
|
||||
pluginList->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
||||
Layout();
|
||||
}
|
||||
|
||||
void Editor::IsSorted(bool sorted) {
|
||||
if (sorted) {
|
||||
applyBtn->SetLabel(translate("Apply Load Order"));
|
||||
} else {
|
||||
if (!showRecalcButton) {
|
||||
recalcBtn->Show(false);
|
||||
applyBtn->SetLabel(translate("Save Changes"));
|
||||
}
|
||||
Layout();
|
||||
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
SetIcon(wxIconLocation("BOSS.exe"));
|
||||
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void Editor::OnPluginSelect(wxListEvent& event) {
|
||||
@@ -644,18 +633,18 @@ void Editor::OnRowSelect(wxListEvent& event) {
|
||||
void Editor::OnQuit(wxCommandEvent& event) {
|
||||
if (event.GetId() == BUTTON_Apply) {
|
||||
//Save edits to userlist.
|
||||
/* YAML::Emitter yout;
|
||||
YAML::Emitter yout;
|
||||
yout.SetIndent(2);
|
||||
yout << YAML::BeginMap
|
||||
<< YAML::Key << "plugins" << YAML::Value << _editedPlugins
|
||||
<< YAML::EndMap;
|
||||
|
||||
ofstream out(game.UserlistPath().string().c_str());
|
||||
ofstream out(_game.UserlistPath().string().c_str());
|
||||
out << yout.c_str();
|
||||
out.close();
|
||||
*/
|
||||
|
||||
if (recalcBtn->IsShown()) {
|
||||
//Signal that the load order should be written.
|
||||
//Signal that the load order should be written and the log opened.
|
||||
}
|
||||
}
|
||||
Close();
|
||||
|
||||
+4
-5
@@ -34,10 +34,7 @@
|
||||
|
||||
class Editor : public wxFrame {
|
||||
public:
|
||||
Editor(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetList(const std::vector<boss::Plugin>& basePlugins, const std::vector<boss::Plugin>& editedPlugins);
|
||||
void IsSorted(bool sorted);
|
||||
Editor(wxWindow *parent, const wxString& title, const boss::Game& game, const std::vector<boss::Plugin>& basePlugins, std::vector<boss::Plugin>& editedPlugins, bool showRecalcButton);
|
||||
|
||||
void OnPluginSelect(wxListEvent& event);
|
||||
void OnEnabledToggle(wxCommandEvent& event);
|
||||
@@ -69,7 +66,9 @@ private:
|
||||
wxSpinCtrl * prioritySpin;
|
||||
wxStaticText * pluginText;
|
||||
|
||||
std::vector<boss::Plugin> _basePlugins, _editedPlugins;
|
||||
const boss::Game& _game;
|
||||
const std::vector<boss::Plugin> _basePlugins;
|
||||
std::vector<boss::Plugin> _editedPlugins;
|
||||
|
||||
void ApplyEdits(const wxString& plugin);
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <boost/format.hpp>
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#include "error.h" //Something in wxWidgets has a #define that conflicts with the error codes.
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
# include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
+56
-81
@@ -20,13 +20,15 @@
|
||||
along with BOSS. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "editor.h"
|
||||
|
||||
#include "../globals.h"
|
||||
#include "../metadata.h"
|
||||
#include "../parsers.h"
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "editor.h"
|
||||
#include "../error.h"
|
||||
#include "../helpers.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <algorithm>
|
||||
@@ -256,8 +258,28 @@ Launcher::Launcher(const wxChar *title, YAML::Node& settings, Game& game, const
|
||||
|
||||
if (!fs::exists(_game.ResultsPath()))
|
||||
ViewButton->Enable(false);
|
||||
|
||||
DisableUndetectedGames();
|
||||
|
||||
//Disable the menu items for the undetected games.
|
||||
GameMenu->FindItem(MENU_Oblivion)->Enable(false);
|
||||
GameMenu->FindItem(MENU_Nehrim)->Enable(false);
|
||||
GameMenu->FindItem(MENU_Skyrim)->Enable(false);
|
||||
GameMenu->FindItem(MENU_Fallout3)->Enable(false);
|
||||
GameMenu->FindItem(MENU_FalloutNewVegas)->Enable(false);
|
||||
for (size_t i=0; i < _detectedGames.size(); i++) {
|
||||
if (_detectedGames[i] == GAME_TES4)
|
||||
GameMenu->FindItem(MENU_Oblivion)->Enable();
|
||||
else if (_detectedGames[i] == GAME_NEHRIM)
|
||||
GameMenu->FindItem(MENU_Nehrim)->Enable();
|
||||
else if (_detectedGames[i] == GAME_TES5)
|
||||
GameMenu->FindItem(MENU_Skyrim)->Enable();
|
||||
else if (_detectedGames[i] == GAME_FO3)
|
||||
GameMenu->FindItem(MENU_Fallout3)->Enable();
|
||||
else if (_detectedGames[i] == GAME_FONV)
|
||||
GameMenu->FindItem(MENU_FalloutNewVegas)->Enable();
|
||||
}
|
||||
|
||||
//Set title bar text.
|
||||
SetTitle(FromUTF8("BOSS - " + _game.Name()));
|
||||
|
||||
//Now set the layout and sizes.
|
||||
SetMenuBar(MenuBar);
|
||||
@@ -330,6 +352,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
this);
|
||||
return;
|
||||
}
|
||||
if (mlist["globals"])
|
||||
mlist_messages = mlist["globals"].as< list<boss::Message> >();
|
||||
@@ -353,6 +376,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
this);
|
||||
return;
|
||||
}
|
||||
if (ulist["globals"])
|
||||
ulist_messages = ulist["globals"].as< list<boss::Message> >();
|
||||
@@ -398,7 +422,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
for (list<boss::Plugin>::iterator it=plugins.begin(), endIt=plugins.end(); it != endIt; ++it) {
|
||||
try {
|
||||
it->EvalAllConditions(game);
|
||||
it->EvalAllConditions(game);
|
||||
} catch (boss::error& e) {
|
||||
//LOG_ERROR("Error: %s", e.what());
|
||||
wxMessageBox(
|
||||
@@ -406,6 +430,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,64 +516,42 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
progDia->Destroy();
|
||||
|
||||
//Create editor window.
|
||||
Editor *editor = new Editor(this, translate("BOSS: Metadata Editor"));
|
||||
|
||||
//The 'plugins' list contains the merged plugin info, but we want to pass a vector of plugins with only masterlist info in its place, so have to construct that.
|
||||
vector<boss::Plugin> pluginVec;
|
||||
for (list<boss::Plugin>::const_iterator it=plugins.begin(), endit=plugins.end(); it != endit; ++it) {
|
||||
boss::Plugin p = *it;
|
||||
list<boss::Plugin>::iterator pos = std::find(mlist_plugins.begin(), mlist_plugins.end(), *it);
|
||||
|
||||
if (pos != mlist_plugins.end())
|
||||
p.Merge(*pos);
|
||||
|
||||
pluginVec.push_back(p);
|
||||
}
|
||||
vector<boss::Plugin> ulistPluginVec(ulist_plugins.begin(), ulist_plugins.end());
|
||||
|
||||
//Pass plugin lists to editor window.
|
||||
editor->SetList(pluginVec, ulistPluginVec);
|
||||
|
||||
//Tell the editor that it's not being shown as part of the load order sort process.
|
||||
editor->IsSorted(true);
|
||||
|
||||
editor->Show();
|
||||
|
||||
//Now a results report definitely exists.
|
||||
ViewButton->Enable(true);
|
||||
}
|
||||
|
||||
void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
//Parse the userlist and masterlist and get a list of installed plugins.
|
||||
|
||||
vector<boss::Plugin> plugins;
|
||||
YAML::Node mlist, ulist;
|
||||
vector<boss::Plugin> mlist_plugins, ulist_plugins;
|
||||
|
||||
//Should probably check for masterlist updates before opening metadata editor.
|
||||
vector<boss::Plugin> installed, mlist_plugins, ulist_plugins;
|
||||
|
||||
//Scan for installed plugins.
|
||||
for (fs::directory_iterator it(_game.DataPath()); it != fs::directory_iterator(); ++it) {
|
||||
if (fs::is_regular_file(it->status()) && (it->path().extension().string() == ".esp" || it->path().extension().string() == ".esm")) {
|
||||
|
||||
boss::Plugin plugin(it->path().filename().string());
|
||||
plugins.push_back(plugin);
|
||||
installed.push_back(boss::Plugin(it->path().filename().string()));
|
||||
}
|
||||
}
|
||||
|
||||
//Parse masterlist.
|
||||
if (fs::exists(_game.MasterlistPath())) {
|
||||
YAML::Node mlist;
|
||||
try {
|
||||
mlist = YAML::LoadFile(_game.MasterlistPath().string());
|
||||
} catch (YAML::ParserException& e) {
|
||||
//LOG_ERROR("Error: %s", e.getString().c_str());
|
||||
wxMessageBox(
|
||||
FromUTF8(format(loc::translate("Error: Masterlist parsing failed. %1%")) % e.what()),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
this);
|
||||
FromUTF8(format(loc::translate("Error: Masterlist parsing failed. %1%")) % e.what()),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
this);
|
||||
}
|
||||
if (mlist["plugins"])
|
||||
mlist_plugins = mlist["plugins"].as< vector<boss::Plugin> >();
|
||||
}
|
||||
|
||||
//Parse userlist.
|
||||
if (fs::exists(_game.UserlistPath())) {
|
||||
YAML::Node ulist;
|
||||
try {
|
||||
ulist = YAML::LoadFile(_game.UserlistPath().string());
|
||||
} catch (YAML::ParserException& e) {
|
||||
@@ -563,31 +566,25 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
ulist_plugins = ulist["plugins"].as< vector<boss::Plugin> >();
|
||||
}
|
||||
|
||||
//Cut out any plugins in the masterlist that aren't installed or in the userlist.
|
||||
//Merge down to the plugin list so that it holds all uneditable metadata.
|
||||
list<boss::Plugin> slim_mlist;
|
||||
|
||||
//Merge the masterlist down into the installed mods list.
|
||||
for (vector<boss::Plugin>::const_iterator it=mlist_plugins.begin(), endit=mlist_plugins.end(); it != endit; ++it) {
|
||||
vector<boss::Plugin>::iterator pos = std::find(plugins.begin(), plugins.end(), *it);
|
||||
vector<boss::Plugin>::iterator pos = find(installed.begin(), installed.end(), *it);
|
||||
|
||||
if (pos != plugins.end())
|
||||
if (pos != installed.end())
|
||||
pos->Merge(*it);
|
||||
else if (std::find(ulist_plugins.begin(), ulist_plugins.end(), *it) != ulist_plugins.end())
|
||||
plugins.push_back(*it);
|
||||
}
|
||||
|
||||
//Add empty entries for any userlist entries that aren't installed.
|
||||
for (vector<boss::Plugin>::const_iterator it=ulist_plugins.begin(), endit=ulist_plugins.end(); it != endit; ++it) {
|
||||
if (find(installed.begin(), installed.end(), *it) == installed.end())
|
||||
installed.push_back(boss::Plugin(it->Name()));
|
||||
}
|
||||
|
||||
//Sort into alphabetical order.
|
||||
std::sort(plugins.begin(), plugins.end(), AlphaSortPlugins);
|
||||
std::sort(ulist_plugins.begin(), ulist_plugins.end(), AlphaSortPlugins);
|
||||
std::sort(installed.begin(), installed.end(), AlphaSortPlugins);
|
||||
|
||||
//Create editor window.
|
||||
Editor *editor = new Editor(this, translate("BOSS: Metadata Editor"));
|
||||
|
||||
//Pass plugin lists to editor window.
|
||||
editor->SetList(plugins, ulist_plugins);
|
||||
|
||||
//Tell the editor that it's not being shown as part of the load order sort process.
|
||||
editor->IsSorted(false);
|
||||
Editor *editor = new Editor(this, translate("BOSS: Metadata Editor"), _game, installed, ulist_plugins, false);
|
||||
|
||||
editor->Show();
|
||||
}
|
||||
@@ -671,28 +668,6 @@ void Launcher::OnAbout(wxCommandEvent& event) {
|
||||
wxAboutBox(aboutInfo);
|
||||
}
|
||||
|
||||
void Launcher::DisableUndetectedGames() {
|
||||
GameMenu->FindItem(MENU_Oblivion)->Enable(false);
|
||||
GameMenu->FindItem(MENU_Nehrim)->Enable(false);
|
||||
GameMenu->FindItem(MENU_Skyrim)->Enable(false);
|
||||
GameMenu->FindItem(MENU_Fallout3)->Enable(false);
|
||||
GameMenu->FindItem(MENU_FalloutNewVegas)->Enable(false);
|
||||
for (size_t i=0; i < _detectedGames.size(); i++) {
|
||||
if (_detectedGames[i] == GAME_TES4)
|
||||
GameMenu->FindItem(MENU_Oblivion)->Enable();
|
||||
else if (_detectedGames[i] == GAME_NEHRIM)
|
||||
GameMenu->FindItem(MENU_Nehrim)->Enable();
|
||||
else if (_detectedGames[i] == GAME_TES5)
|
||||
GameMenu->FindItem(MENU_Skyrim)->Enable();
|
||||
else if (_detectedGames[i] == GAME_FO3)
|
||||
GameMenu->FindItem(MENU_Fallout3)->Enable();
|
||||
else if (_detectedGames[i] == GAME_FONV)
|
||||
GameMenu->FindItem(MENU_FalloutNewVegas)->Enable();
|
||||
}
|
||||
|
||||
SetTitle(FromUTF8("BOSS - " + _game.Name()));
|
||||
}
|
||||
|
||||
bool Launcher::AlphaSortPlugins(const boss::Plugin& lhs, const boss::Plugin& rhs) {
|
||||
return boost::to_lower_copy(lhs.Name()) < boost::to_lower_copy(rhs.Name());
|
||||
}
|
||||
|
||||
@@ -64,8 +64,6 @@ private:
|
||||
boss::Game& _game;
|
||||
YAML::Node& _settings; //BOSS Settings.
|
||||
const std::vector<unsigned int>& _detectedGames;
|
||||
|
||||
void DisableUndetectedGames();
|
||||
|
||||
static bool AlphaSortPlugins(const boss::Plugin& lhs, const boss::Plugin& rhs);
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "helpers.h"
|
||||
#include "metadata.h"
|
||||
#include "parsers.h"
|
||||
|
||||
#include <src/playground.h>
|
||||
|
||||
@@ -106,6 +107,38 @@ namespace boss {
|
||||
data = d;
|
||||
}
|
||||
|
||||
bool ConditionalData::EvalCondition(boss::Game& game) const {
|
||||
if (condition.empty())
|
||||
return true;
|
||||
|
||||
boost::unordered_map<std::string, bool>::const_iterator it = game.conditionCache.find(boost::to_lower_copy(condition));
|
||||
if (it != game.conditionCache.end())
|
||||
return it->second;
|
||||
|
||||
condition_grammar<std::string::const_iterator, boost::spirit::qi::space_type> grammar;
|
||||
boost::spirit::qi::space_type skipper;
|
||||
std::string::const_iterator begin, end;
|
||||
bool eval;
|
||||
|
||||
grammar.SetGame(game);
|
||||
begin = condition.begin();
|
||||
end = condition.end();
|
||||
|
||||
bool r;
|
||||
try {
|
||||
r = boost::spirit::qi::phrase_parse(begin, end, grammar, skipper, eval);
|
||||
} catch (boss::error& e) {
|
||||
throw boss::error(boss::ERROR_PATH_READ_FAIL, "Parsing of condition \"" + condition + "\" failed: " + e.what());
|
||||
}
|
||||
|
||||
if (!r || begin != end)
|
||||
throw boss::error(boss::ERROR_PATH_READ_FAIL, "Parsing of condition \"" + condition + "\" failed!");
|
||||
|
||||
game.conditionCache.emplace(boost::to_lower_copy(condition), eval);
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
Message::Message() {}
|
||||
|
||||
Message::Message(const std::string& t, const std::string& cont)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* BOSS
|
||||
|
||||
A plugin load order optimiser for games that use the esp/esm plugin system.
|
||||
|
||||
Copyright (C) 2012-2013 WrinklyNinja
|
||||
|
||||
This file is part of BOSS.
|
||||
|
||||
BOSS is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
BOSS is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with BOSS. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __BOSS_NETWORK__
|
||||
#define __BOSS_NETWORK__
|
||||
|
||||
namespace boss {
|
||||
|
||||
/* Need to be able to:
|
||||
|
||||
- Check if there's an internet connection.
|
||||
- Get the revision number for the local masterlist, if present.
|
||||
- Get the revision number for the remote masterlist.
|
||||
- Compare the two revision numbers.
|
||||
- Download the remote masterlist if it has a higher revision number.
|
||||
- Test that the downloaded masterlist is valid by parsing it to see if any errors come up.
|
||||
- If the downloaded masterlist is parsed OK, replace the local masterlist with it.
|
||||
*/
|
||||
}
|
||||
+4
-36
@@ -211,7 +211,7 @@ namespace YAML {
|
||||
out << EndSeq;
|
||||
}
|
||||
|
||||
Emitter& operator << (Emitter& out, const boss::Message& rhs) {
|
||||
inline Emitter& operator << (Emitter& out, const boss::Message& rhs) {
|
||||
out << BeginMap
|
||||
<< Key << "type" << Value << rhs.Type()
|
||||
<< Key << "content" << Value << rhs.Content();
|
||||
@@ -225,7 +225,7 @@ namespace YAML {
|
||||
out << EndMap;
|
||||
}
|
||||
|
||||
Emitter& operator << (Emitter& out, const boss::File& rhs) {
|
||||
inline Emitter& operator << (Emitter& out, const boss::File& rhs) {
|
||||
if (!rhs.IsConditional() && rhs.DisplayName().empty())
|
||||
out << rhs.Name();
|
||||
else {
|
||||
@@ -242,7 +242,7 @@ namespace YAML {
|
||||
}
|
||||
}
|
||||
|
||||
Emitter& operator << (Emitter& out, const boss::Tag& rhs) {
|
||||
inline Emitter& operator << (Emitter& out, const boss::Tag& rhs) {
|
||||
if (!rhs.IsConditional())
|
||||
out << rhs.PrefixedName();
|
||||
else {
|
||||
@@ -253,7 +253,7 @@ namespace YAML {
|
||||
}
|
||||
}
|
||||
|
||||
Emitter& operator << (Emitter& out, const boss::Plugin& rhs) {
|
||||
inline Emitter& operator << (Emitter& out, const boss::Plugin& rhs) {
|
||||
//if (!rhs.HasNameOnly()) {
|
||||
|
||||
out << BeginMap
|
||||
@@ -521,37 +521,5 @@ namespace boss {
|
||||
return !boost::contains(parent_path, "../../");
|
||||
}
|
||||
};
|
||||
|
||||
bool ConditionalData::EvalCondition(boss::Game& game) const {
|
||||
if (condition.empty())
|
||||
return true;
|
||||
|
||||
boost::unordered_map<std::string, bool>::const_iterator it = game.conditionCache.find(boost::to_lower_copy(condition));
|
||||
if (it != game.conditionCache.end())
|
||||
return it->second;
|
||||
|
||||
condition_grammar<std::string::const_iterator, qi::space_type> grammar;
|
||||
qi::space_type skipper;
|
||||
std::string::const_iterator begin, end;
|
||||
bool eval;
|
||||
|
||||
grammar.SetGame(game);
|
||||
begin = condition.begin();
|
||||
end = condition.end();
|
||||
|
||||
bool r;
|
||||
try {
|
||||
r = qi::phrase_parse(begin, end, grammar, skipper, eval);
|
||||
} catch (boss::error& e) {
|
||||
throw boss::error(boss::ERROR_PATH_READ_FAIL, "Parsing of condition \"" + condition + "\" failed: " + e.what());
|
||||
}
|
||||
|
||||
if (!r || begin != end)
|
||||
throw boss::error(boss::ERROR_PATH_READ_FAIL, "Parsing of condition \"" + condition + "\" failed!");
|
||||
|
||||
game.conditionCache.emplace(boost::to_lower_copy(condition), eval);
|
||||
|
||||
return eval;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user