diff options
author | David Robillard <d@drobilla.net> | 2008-08-02 20:12:58 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-08-02 20:12:58 +0000 |
commit | 925022321b8f7dba8b10993a9cd32c0cc0b45e0d (patch) | |
tree | ad2dde7d67af4d9626291298cffe0ba3f4941d59 | |
parent | f7eab5b56d8b77b3e0cd0b42ff5a94aae69942ca (diff) | |
download | patchage-925022321b8f7dba8b10993a9cd32c0cc0b45e0d.tar.gz patchage-925022321b8f7dba8b10993a9cd32c0cc0b45e0d.tar.bz2 patchage-925022321b8f7dba8b10993a9cd32c0cc0b45e0d.zip |
Apply module split restoration patch from Nedko.
git-svn-id: http://svn.drobilla.net/lad/patchage@1317 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | src/PatchageModule.hpp | 6 | ||||
-rw-r--r-- | src/StateManager.cpp | 142 | ||||
-rw-r--r-- | src/StateManager.hpp | 25 |
3 files changed, 117 insertions, 56 deletions
diff --git a/src/PatchageModule.hpp b/src/PatchageModule.hpp index 8828fcc..c8878aa 100644 --- a/src/PatchageModule.hpp +++ b/src/PatchageModule.hpp @@ -68,9 +68,9 @@ public: if (!canvas) return; - Coord loc = _app->state_manager()->get_module_location(_name, _type); + Coord loc; - if (loc.x != -1) + if (_app->state_manager()->get_module_location(_name, _type, loc)) move_to(loc.x, loc.y); else move_to((canvas->width()/2) - 100 + rand() % 400, @@ -78,7 +78,7 @@ public: } virtual void store_location() { - Coord loc = { property_x().get_value(), property_y().get_value() }; + Coord loc(property_x().get_value(), property_y().get_value()); _app->state_manager()->set_module_location(_name, _type, loc); } diff --git a/src/StateManager.cpp b/src/StateManager.cpp index fa82f8a..78a0e0d 100644 --- a/src/StateManager.cpp +++ b/src/StateManager.cpp @@ -35,33 +35,66 @@ StateManager::StateManager() } -Coord -StateManager::get_module_location(const string& name, ModuleType type) +bool +StateManager::get_module_location(const string& name, ModuleType type, Coord& loc) { - for (std::list<ModuleLocation>::iterator i = _module_locations.begin(); i != _module_locations.end(); ++i) { - if ((*i).name == name && (*i).type == type) - return (*i).loc; + map<string, ModuleSettings>::const_iterator i = _module_settings.find(name); + if (i == _module_settings.end()) + { + return false; + } + + const ModuleSettings& settings = (*i).second; + switch (type) + { + case Input: + loc = settings.input_location; + goto check; + case Output: + loc = settings.output_location; + goto check; + case InputOutput: + loc = settings.inout_location; + goto check; + default: + throw std::runtime_error("Invalid module type"); } - // -1 used as a flag value - Coord r = { -1, -1 }; - return r; + return false; + +check: + return loc.x != UNINITIALIZED_COORD; } void StateManager::set_module_location(const string& name, ModuleType type, Coord loc) { - for (std::list<ModuleLocation>::iterator i = _module_locations.begin(); i != _module_locations.end(); ++i) { - if ((*i).name == name && (*i).type == type) { - (*i).loc = loc; - return; - } +retry: + map<string, ModuleSettings>::iterator i = _module_settings.find(name); + if (i == _module_settings.end()) + { + // no mapping exists, insert new element and set its split type, then retry to retrieve reference to it + _module_settings[name].split = type != InputOutput; + goto retry; + } + + ModuleSettings& settings_ref = (*i).second; + + switch (type) + { + case Input: + settings_ref.input_location = loc; + break; + case Output: + settings_ref.output_location = loc; + break; + case InputOutput: + settings_ref.inout_location = loc; + break; + default: + throw std::runtime_error("Invalid module type"); } - - // If we get here, module isn't in list yet - ModuleLocation ml = { name, type, loc }; - _module_locations.push_back(ml); } @@ -73,25 +106,27 @@ StateManager::set_module_location(const string& name, ModuleType type, Coord loc bool StateManager::get_module_split(const string& name, bool default_val) const { - map<string, bool>::const_iterator i = _module_splits.find(name); - if (i == _module_splits.end()) + map<string, ModuleSettings>::const_iterator i = _module_settings.find(name); + if (i == _module_settings.end()) + { return default_val; - else - return (*i).second; + } + + return (*i).second.split; } void StateManager::set_module_split(const string& name, bool split) { - _module_splits[name] = split; + _module_settings[name].split = split; } void StateManager::load(const string& filename) { - _module_locations.clear(); + _module_settings.clear(); cerr << "Loading configuration file " << filename << endl; @@ -131,7 +166,10 @@ StateManager::load(const string& filename) is >> s; _zoom = atof(s.c_str()); - ModuleLocation ml; + Coord loc; + ModuleType type; + string name; + while (1) { is >> s; if (is.eof()) break; @@ -139,37 +177,48 @@ StateManager::load(const string& filename) // Old versions didn't quote, so need to support both :/ if (s[0] == '\"') { if (s.length() > 1 && s[s.length()-1] == '\"') { - ml.name = s.substr(1, s.length()-2); + name = s.substr(1, s.length()-2); } else { - ml.name = s.substr(1); + name = s.substr(1); is >> s; while (s[s.length()-1] != '\"') { - ml.name.append(" ").append(s); + name.append(" ").append(s); is >> s; } - ml.name.append(" ").append(s.substr(0, s.length()-1)); + name.append(" ").append(s.substr(0, s.length()-1)); } } else { - ml.name = s; + name = s; } is >> s; - if (s == "input") ml.type = Input; - else if (s == "output") ml.type = Output; - else if (s == "inputoutput") ml.type = InputOutput; + if (s == "input") type = Input; + else if (s == "output") type = Output; + else if (s == "inputoutput") type = InputOutput; else throw std::runtime_error("Corrupt settings file."); is >> s; - ml.loc.x = atoi(s.c_str()); + loc.x = atoi(s.c_str()); is >> s; - ml.loc.y = atoi(s.c_str()); + loc.y = atoi(s.c_str()); - _module_locations.push_back(ml); + set_module_location(name, type, loc); } is.close(); } +static +inline +void +write_module_settings_entry( + std::ofstream& os, + const string& name, + const char * type, + const Coord& loc) +{ + os << "\"" << name << "\"" << " " << type << " " << loc.x << " " << loc.y << std::endl; +} void StateManager::save(const string& filename) @@ -181,17 +230,20 @@ StateManager::save(const string& filename) os << "window_size " << _window_size.x << " " << _window_size.y << std::endl; os << "zoom_level " << _zoom << std::endl; - ModuleLocation ml; - for (std::list<ModuleLocation>::iterator i = _module_locations.begin(); i != _module_locations.end(); ++i) { - ml = *i; - os << "\"" << ml.name << "\""; - - if (ml.type == Input) os << " input "; - else if (ml.type == Output) os << " output "; - else if (ml.type == InputOutput) os << " inputoutput "; - else throw std::runtime_error("Invalid module type"); - os << ml.loc.x << " " << ml.loc.y << std::endl; + for (map<string, ModuleSettings>::iterator i = _module_settings.begin(); i != _module_settings.end(); ++i) { + const ModuleSettings& settings = (*i).second; + const string& name = (*i).first; + + if (settings.split) + { + write_module_settings_entry(os, name, "input", settings.input_location); + write_module_settings_entry(os, name, "output", settings.output_location); + } + else + { + write_module_settings_entry(os, name, "inputoutput", settings.inout_location); + } } os.close(); diff --git a/src/StateManager.hpp b/src/StateManager.hpp index 757c2e9..12cdbb9 100644 --- a/src/StateManager.hpp +++ b/src/StateManager.hpp @@ -25,7 +25,15 @@ #include "PatchagePort.hpp" enum ModuleType { Input, Output, InputOutput }; -struct Coord { double x; double y; }; + +#define UNINITIALIZED_COORD -1 +struct Coord +{ + Coord() { x = UNINITIALIZED_COORD; y = UNINITIALIZED_COORD; } + Coord(double x_, double y_) : x(x_), y(y_) {} + double x; + double y; +}; class StateManager { @@ -35,7 +43,7 @@ public: void load(const std::string& filename); void save(const std::string& filename); - Coord get_module_location(const std::string& name, ModuleType type); + bool get_module_location(const std::string& name, ModuleType type, Coord& loc); void set_module_location(const std::string& name, ModuleType type, Coord loc); void set_module_split(const std::string& name, bool split); @@ -52,14 +60,15 @@ public: void set_window_size(Coord size) { _window_size = size; } private: - struct ModuleLocation { - std::string name; - ModuleType type; // for distinguishing terminal modules (input or output) - Coord loc; + struct ModuleSettings { + ModuleSettings() { split = false; }; + bool split; + Coord input_location; + Coord output_location; + Coord inout_location; }; - std::list<ModuleLocation> _module_locations; - std::map<std::string,bool> _module_splits; + std::map<std::string,ModuleSettings> _module_settings; Coord _window_location; Coord _window_size; float _zoom; |