summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-08-02 20:12:58 +0000
committerDavid Robillard <d@drobilla.net>2008-08-02 20:12:58 +0000
commit925022321b8f7dba8b10993a9cd32c0cc0b45e0d (patch)
treead2dde7d67af4d9626291298cffe0ba3f4941d59
parentf7eab5b56d8b77b3e0cd0b42ff5a94aae69942ca (diff)
downloadpatchage-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.hpp6
-rw-r--r--src/StateManager.cpp142
-rw-r--r--src/StateManager.hpp25
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;