aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-10 21:23:14 +0000
committerDavid Robillard <d@drobilla.net>2011-01-10 21:23:14 +0000
commitf293da6bc4f0f631c086d35666e3e8bfef19b8f2 (patch)
treed0e693bdec5e4a53daca500434533d2fc5c43650 /src
parentdb319f5a8cb7915b2d5b93adab148fa16d92e7e5 (diff)
downloadmachina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.tar.gz
machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.tar.bz2
machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.zip
Rewrite with UI/engine split.
Note some things aren't quite working right again yet... git-svn-id: http://svn.drobilla.net/lad/trunk/machina@2821 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/engine/Action.cpp3
-rw-r--r--src/engine/Action.hpp (renamed from src/engine/machina/Action.hpp)3
-rw-r--r--src/engine/ActionFactory.cpp4
-rw-r--r--src/engine/ActionFactory.hpp (renamed from src/engine/machina/ActionFactory.hpp)0
-rw-r--r--src/engine/Edge.cpp11
-rw-r--r--src/engine/Edge.hpp (renamed from src/engine/machina/Edge.hpp)5
-rw-r--r--src/engine/Engine.cpp86
-rw-r--r--src/engine/JackDriver.cpp20
-rw-r--r--src/engine/JackDriver.hpp3
-rw-r--r--src/engine/LearnRequest.cpp28
-rw-r--r--src/engine/LearnRequest.hpp31
-rw-r--r--src/engine/Loader.cpp12
-rw-r--r--src/engine/Machine.cpp37
-rw-r--r--src/engine/MachineBuilder.cpp6
-rw-r--r--src/engine/MidiAction.cpp6
-rw-r--r--src/engine/MidiAction.hpp (renamed from src/engine/machina/MidiAction.hpp)4
-rw-r--r--src/engine/Mutation.cpp7
-rw-r--r--src/engine/Node.cpp51
-rw-r--r--src/engine/Node.hpp (renamed from src/engine/machina/Node.hpp)15
-rw-r--r--src/engine/Problem.cpp4
-rw-r--r--src/engine/SMFDriver.cpp18
-rw-r--r--src/engine/SMFDriver.hpp (renamed from src/engine/machina/SMFDriver.hpp)2
-rw-r--r--src/engine/Stateful.cpp4
-rw-r--r--src/engine/Stateful.hpp (renamed from src/engine/machina/Stateful.hpp)19
-rw-r--r--src/engine/machina/Driver.hpp11
-rw-r--r--src/engine/machina/Engine.hpp17
-rw-r--r--src/engine/machina/Machine.hpp8
-rw-r--r--src/engine/machina/types.hpp6
-rw-r--r--src/engine/wscript5
-rw-r--r--src/gui/EdgeView.cpp64
-rw-r--r--src/gui/EdgeView.hpp30
-rw-r--r--src/gui/GladeXml.hpp3
-rw-r--r--src/gui/MachinaCanvas.cpp192
-rw-r--r--src/gui/MachinaCanvas.hpp30
-rw-r--r--src/gui/MachinaGUI.cpp86
-rw-r--r--src/gui/MachinaGUI.hpp36
-rw-r--r--src/gui/NodePropertiesWindow.cpp20
-rw-r--r--src/gui/NodePropertiesWindow.hpp18
-rw-r--r--src/gui/NodeView.cpp130
-rw-r--r--src/gui/NodeView.hpp42
-rw-r--r--src/gui/main.cpp4
-rw-r--r--src/gui/wscript4
-rw-r--r--src/machina.cpp1
-rw-r--r--src/midi2machina.cpp1
44 files changed, 651 insertions, 436 deletions
diff --git a/src/engine/Action.cpp b/src/engine/Action.cpp
index 14f7158..67a41c2 100644
--- a/src/engine/Action.cpp
+++ b/src/engine/Action.cpp
@@ -17,7 +17,8 @@
#include "redlandmm/World.hpp"
#include "redlandmm/Model.hpp"
-#include "machina/Action.hpp"
+
+#include "Action.hpp"
namespace Machina {
diff --git a/src/engine/machina/Action.hpp b/src/engine/Action.hpp
index 84181a3..ceeea6a 100644
--- a/src/engine/machina/Action.hpp
+++ b/src/engine/Action.hpp
@@ -25,8 +25,9 @@
#include "raul/SharedPtr.hpp"
#include "raul/TimeSlice.hpp"
+#include "machina/types.hpp"
+
#include "Stateful.hpp"
-#include "types.hpp"
namespace Machina {
diff --git a/src/engine/ActionFactory.cpp b/src/engine/ActionFactory.cpp
index d486c7d..d5fc954 100644
--- a/src/engine/ActionFactory.cpp
+++ b/src/engine/ActionFactory.cpp
@@ -15,8 +15,8 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "machina/ActionFactory.hpp"
-#include "machina/MidiAction.hpp"
+#include "ActionFactory.hpp"
+#include "MidiAction.hpp"
namespace Machina {
diff --git a/src/engine/machina/ActionFactory.hpp b/src/engine/ActionFactory.hpp
index 04b0c74..04b0c74 100644
--- a/src/engine/machina/ActionFactory.hpp
+++ b/src/engine/ActionFactory.hpp
diff --git a/src/engine/Edge.cpp b/src/engine/Edge.cpp
index 47335fb..8acdca3 100644
--- a/src/engine/Edge.cpp
+++ b/src/engine/Edge.cpp
@@ -17,13 +17,20 @@
#include "raul/Atom.hpp"
#include "raul/AtomRDF.hpp"
+
#include "redlandmm/World.hpp"
#include "redlandmm/Model.hpp"
-#include "machina/Node.hpp"
-#include "machina/Edge.hpp"
+
+#include "Edge.hpp"
+#include "Node.hpp"
namespace Machina {
+void
+Edge::set(URIInt key, const Raul::Atom& value)
+{
+ std::cout << "EDGE SET " << key << " = " << value << std::endl;
+}
void
Edge::write_state(Redland::Model& model)
diff --git a/src/engine/machina/Edge.hpp b/src/engine/Edge.hpp
index 8a2d1c2..8e34292 100644
--- a/src/engine/machina/Edge.hpp
+++ b/src/engine/Edge.hpp
@@ -25,9 +25,10 @@
#include "raul/SharedPtr.hpp"
#include "raul/WeakPtr.hpp"
+#include "machina/types.hpp"
+
#include "Action.hpp"
#include "Stateful.hpp"
-#include "types.hpp"
namespace Machina {
@@ -35,13 +36,13 @@ class Node;
class Edge : public Stateful {
public:
-
Edge(WeakPtr<Node> tail, SharedPtr<Node> head)
: _probability(1.0f)
, _tail(tail)
, _head(head)
{}
+ void set(URIInt key, const Raul::Atom& value);
void write_state(Redland::Model& model);
WeakPtr<Node> tail() { return _tail; }
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp
index 612176a..03762b6 100644
--- a/src/engine/Engine.cpp
+++ b/src/engine/Engine.cpp
@@ -21,13 +21,21 @@
#include "machina/Engine.hpp"
#include "machina/Loader.hpp"
#include "machina/Machine.hpp"
-#include "machina/SMFDriver.hpp"
+#include "SMFDriver.hpp"
#ifdef HAVE_JACK
#include "JackDriver.hpp"
#endif
namespace Machina {
+Engine::Engine(SharedPtr<Driver> driver, Redland::World& rdf_world)
+ : _driver(driver)
+ , _rdf_world(rdf_world)
+ , _loader(_rdf_world)
+{
+}
+
+
SharedPtr<Driver>
Engine::new_driver(const std::string& name, SharedPtr<Machine> machine)
{
@@ -39,7 +47,7 @@ Engine::new_driver(const std::string& name, SharedPtr<Machine> machine)
}
#endif
if (name == "smf")
- return SharedPtr<Driver>(new SMFDriver(machine));
+ return SharedPtr<Driver>(new SMFDriver(machine->time().unit()));
std::cerr << "Error: Unknown driver type `" << name << "'" << std::endl;
return SharedPtr<Driver>();
@@ -51,54 +59,68 @@ Engine::new_driver(const std::string& name, SharedPtr<Machine> machine)
SharedPtr<Machine>
Engine::load_machine(const Glib::ustring& uri)
{
- SharedPtr<Machine> old_machine = _driver->machine(); // Hold a reference to current machine..
-
- SharedPtr<Machine> m = _loader.load(uri);
- if (m) {
- m->activate();
- _driver->set_machine(m);
+ SharedPtr<Machine> machine = _loader.load(uri);
+ SharedPtr<Machine> old_machine;
+ if (machine) {
+ old_machine = _driver->machine(); // Keep a reference to old machine...
+ machine->activate();
+ _driver->set_machine(machine); // Switch driver to new machine
}
// .. and drop it in this thread (to prevent deallocation in the RT thread)
- return m;
+ return machine;
}
-
-/** Load the machine at @a uri, and insert it into the current machine..
+/** Build a machine from the MIDI at @a uri, and run it (replacing current machine).
* Safe to call while engine is processing.
*/
SharedPtr<Machine>
-Engine::import_machine(const Glib::ustring& uri)
+Engine::load_machine_midi(const Glib::ustring& uri, double q, Raul::TimeDuration dur)
{
- SharedPtr<Machine> m = _loader.load(uri);
- if (m) {
- m->activate();
- _driver->machine()->nodes().append(m->nodes());
+ SharedPtr<SMFDriver> file_driver(new SMFDriver(dur.unit()));
+ SharedPtr<Machine> machine = file_driver->learn(uri, q, dur);
+ SharedPtr<Machine> old_machine;
+ if (machine) {
+ old_machine = _driver->machine(); // Keep a reference to old machine...
+ machine->activate();
+ _driver->set_machine(machine); // Switch driver to new machine
}
- // Discard m
+ // .. and drop it in this thread (to prevent deallocation in the RT thread)
- return _driver->machine();
+ return machine;
}
-
-/** Learn the SMF (MIDI) file at @a uri, add it to the current machine.
- * Safe to call while engine is processing.
- */
-SharedPtr<Machine>
-Engine::import_midi(const Glib::ustring& uri, double q, Raul::TimeDuration duration)
+void
+Engine::import_machine(SharedPtr<Machine> machine)
{
- SharedPtr<SMFDriver> file_driver(new SMFDriver());
- SharedPtr<Machine> m = file_driver->learn(uri, q, duration);
- m->activate();
- _driver->machine()->nodes().append(m->nodes());
-
- // Discard m
-
- return _driver->machine();
+ machine->activate();
+ _driver->machine()->nodes().append(machine->nodes());
+ // FIXME: thread safe?
+ // FIXME: announce
}
+void
+Engine::export_midi(const Glib::ustring& filename, Raul::TimeDuration dur)
+{
+ SharedPtr<Machine> machine = _driver->machine();
+ SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver(dur.unit()));
+
+ const bool activated = _driver->is_activated();
+ if (activated)
+ _driver->deactivate(); // FIXME: disable instead
+
+ machine->set_sink(file_driver->writer());
+ file_driver->writer()->start(filename, TimeStamp(dur.unit(), 0.0));
+ file_driver->run(machine, dur);
+ machine->set_sink(_driver);
+ machine->reset(machine->time());
+ file_driver->writer()->finish();
+
+ if (activated)
+ _driver->activate();
+}
void
Engine::set_bpm(double bpm)
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index 6f3afe0..ca86111 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -19,10 +19,12 @@
#include <iomanip>
#include "machina-config.h"
-#include "machina/MidiAction.hpp"
+#include "machina/URIs.hpp"
+#include "machina/Updates.hpp"
#include "JackDriver.hpp"
#include "LearnRequest.hpp"
+#include "MidiAction.hpp"
#include "jack_compat.h"
using namespace Raul;
@@ -222,6 +224,18 @@ JackDriver::process_input(SharedPtr<Machine> machine, const TimeSlice& time)
learn->finish(
TimeStamp(TimeUnit::frames(sample_rate()),
jack_last_frame_time(_client) + ev.time, 0));
+
+ const uint64_t id = Stateful::next_id();
+ write_set(_updates, id,
+ URIs::instance().rdf_type,
+ URIs::instance().machina_MidiAction_atom);
+ write_set(_updates, learn->node()->id(),
+ URIs::instance().machina_enter_action,
+ Raul::Atom((int32_t)id));
+ write_set(_updates, id,
+ URIs::instance().machina_note_number,
+ Raul::Atom((int32_t)ev.buffer[1]));
+
machine->clear_pending_learn();
}
}
@@ -235,7 +249,7 @@ JackDriver::process_input(SharedPtr<Machine> machine, const TimeSlice& time)
void
JackDriver::write_event(Raul::TimeStamp time,
size_t size,
- const byte* event) throw (std::logic_error)
+ const byte* event)
{
if (!_output_port)
return;
@@ -327,7 +341,7 @@ JackDriver::on_process(jack_nframes_t nframes)
goto end;
while (true) {
- const uint32_t run_dur_frames = machine->run(_cycle_time);
+ const uint32_t run_dur_frames = machine->run(_cycle_time, _updates);
if (run_dur_frames == 0) {
// Machine didn't run at all (machine has no initial states)
diff --git a/src/engine/JackDriver.hpp b/src/engine/JackDriver.hpp
index 756f717..133c7ed 100644
--- a/src/engine/JackDriver.hpp
+++ b/src/engine/JackDriver.hpp
@@ -25,7 +25,6 @@
#include "raul/Command.hpp"
#include "raul/DoubleBuffer.hpp"
-#include "raul/EventRingBuffer.hpp"
#include "raul/Semaphore.hpp"
#include "raul/SharedPtr.hpp"
@@ -61,7 +60,7 @@ public:
void write_event(Raul::TimeStamp time,
size_t size,
- const unsigned char* event) throw (std::logic_error);
+ const unsigned char* event);
void set_bpm(double bpm) { _bpm.set(bpm); }
void set_quantization(double q) { _quantization.set(q); }
diff --git a/src/engine/LearnRequest.cpp b/src/engine/LearnRequest.cpp
index 6643602..b103c65 100644
--- a/src/engine/LearnRequest.cpp
+++ b/src/engine/LearnRequest.cpp
@@ -21,6 +21,34 @@
namespace Machina {
+LearnRequest::LearnRequest(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node)
+ : _started(false)
+ , _start_time(TimeUnit(TimeUnit::BEATS, 19200), 0, 0) // irrelevant
+ , _quantization(0) // irrelevant
+ , _node(node)
+ , _enter_action(new MidiAction(4, NULL))
+ , _exit_action(new MidiAction(4, NULL))
+{
+ maid->manage(_enter_action);
+ maid->manage(_exit_action);
+}
+
+SharedPtr<LearnRequest>
+LearnRequest::create(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node)
+{
+ SharedPtr<LearnRequest> ret(new LearnRequest(maid, node));
+ maid->manage(ret);
+ return ret;
+}
+
+void
+LearnRequest::start(double q, Raul::TimeStamp time)
+{
+ _started = true;
+ _start_time = time;
+ _quantization = q;
+}
+
/** Add the learned actions to the node */
void
LearnRequest::finish(TimeStamp time)
diff --git a/src/engine/LearnRequest.hpp b/src/engine/LearnRequest.hpp
index 7d02564..3de98ea 100644
--- a/src/engine/LearnRequest.hpp
+++ b/src/engine/LearnRequest.hpp
@@ -21,10 +21,11 @@
#include "raul/Maid.hpp"
#include "raul/SharedPtr.hpp"
-#include "machina/MidiAction.hpp"
-#include "machina/Node.hpp"
#include "machina/types.hpp"
+#include "MidiAction.hpp"
+#include "Node.hpp"
+
namespace Machina {
class Node;
@@ -35,38 +36,20 @@ class MidiAction;
*/
class LearnRequest : public Raul::Deletable {
public:
-
static SharedPtr<LearnRequest>
- create(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node)
- {
- SharedPtr<LearnRequest> ret(new LearnRequest(maid, node));
- maid->manage(ret);
- return ret;
- }
-
- void start(double q, Raul::TimeStamp time)
- { _started = true; _start_time = time; _quantization = q; }
+ create(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node);
+ void start(double q, Raul::TimeStamp time);
void finish(TimeStamp time);
- bool started() { return _started; }
+ inline bool started() const { return _started; }
const SharedPtr<Node>& node() { return _node; }
const SharedPtr<MidiAction>& enter_action() { return _enter_action; }
const SharedPtr<MidiAction>& exit_action() { return _exit_action; }
private:
- LearnRequest(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node)
- : _started(false)
- , _start_time(TimeUnit(TimeUnit::BEATS, 19200), 0, 0) // irrelevant
- , _quantization(0) // irrelevant
- , _node(node)
- , _enter_action(new MidiAction(4, NULL))
- , _exit_action(new MidiAction(4, NULL))
- {
- maid->manage(_enter_action);
- maid->manage(_exit_action);
- }
+ LearnRequest(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node);
bool _started;
TimeStamp _start_time;
diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp
index 78992d5..2698491 100644
--- a/src/engine/Loader.cpp
+++ b/src/engine/Loader.cpp
@@ -15,17 +15,21 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <cmath>
#include <iostream>
#include <map>
-#include <cmath>
+
#include <glibmm/ustring.h>
+
#include "redlandmm/Query.hpp"
+
#include "machina/Loader.hpp"
-#include "machina/Node.hpp"
-#include "machina/Edge.hpp"
#include "machina/Machine.hpp"
-#include "machina/ActionFactory.hpp"
+
#include "machina-config.h"
+#include "ActionFactory.hpp"
+#include "Edge.hpp"
+#include "Node.hpp"
using namespace Raul;
using namespace std;
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index 18ce5de..32ac10d 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -17,20 +17,26 @@
#include <cstdlib>
+#include "raul/Atom.hpp"
#include "raul/SharedPtr.hpp"
#include "redlandmm/Model.hpp"
#include "redlandmm/World.hpp"
-#include "machina/Edge.hpp"
#include "machina/Machine.hpp"
-#include "machina/MidiAction.hpp"
-#include "machina/Node.hpp"
+#include "machina/Updates.hpp"
+#include "machina/URIs.hpp"
+#include "Edge.hpp"
+#include "Node.hpp"
#include "LearnRequest.hpp"
+#include "MidiAction.hpp"
using namespace std;
using namespace Raul;
+static const Raul::Atom true_atom(true);
+static const Raul::Atom false_atom(false);
+
namespace Machina {
@@ -162,7 +168,7 @@ Machine::remove_node(SharedPtr<Node> node)
_nodes.erase(_nodes.find(node));
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n)
- (*n)->remove_edges_to(node);
+ (*n)->remove_edge_to(node);
}
@@ -217,7 +223,7 @@ Machine::earliest_node() const
* Returns true if node was entered, or false if the maximum active nodes has been reached.
*/
bool
-Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
+Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
{
assert(!node->is_active());
@@ -229,6 +235,8 @@ Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
node->enter(sink, _time);
assert(node->is_active());
_active_nodes.at(index) = node;
+
+ write_set(updates, node->id(), URIs::instance().machina_active, true_atom);
return true;
}
index = (index + 1) % MAX_ACTIVE_NODES;
@@ -243,9 +251,11 @@ Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
/** Exit an active node at the current _time.
*/
void
-Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
+Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
{
node->exit(sink, _time);
+ write_set(updates, node->id(), URIs::instance().machina_active, false_atom);
+
assert(!node->is_active());
for (size_t i=0; i < MAX_ACTIVE_NODES; ++i)
@@ -267,7 +277,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
&& rand_normal > range_min
&& rand_normal < range_min + (*s)->probability()) {
- enter_node(sink, (*s)->head());
+ enter_node(sink, (*s)->head(), updates);
break;
} else {
@@ -286,7 +296,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
SharedPtr<Node> head = (*e)->head();
if ( ! head->is_active())
- enter_node(sink, head);
+ enter_node(sink, head, updates);
}
}
@@ -304,7 +314,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
* with sample accuracy if necessary).
*/
uint32_t
-Machine::run(const Raul::TimeSlice& time)
+Machine::run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates)
{
if (_is_finished)
return 0;
@@ -321,11 +331,13 @@ Machine::run(const Raul::TimeSlice& time)
bool entered = false;
if ( ! _nodes.empty()) {
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
- if ((*n)->is_active())
+ if ((*n)->is_active()) {
(*n)->exit(sink, _time);
+ write_set(updates, (*n)->id(), URIs::instance().machina_active, false_atom);
+ }
if ((*n)->is_initial()) {
- if (enter_node(sink, (*n)))
+ if (enter_node(sink, (*n), updates))
entered = true;
}
}
@@ -352,7 +364,7 @@ Machine::run(const Raul::TimeSlice& time)
} else if (time.beats_to_ticks(earliest->exit_time()) < cycle_end_frames) {
// Earliest active state ends this cycle
_time = earliest->exit_time();
- exit_node(sink, earliest);
+ exit_node(sink, earliest, updates);
} else {
// Earliest active state ends in the future, done this cycle
@@ -376,7 +388,6 @@ Machine::learn(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node)
_pending_learn = LearnRequest::create(maid, node);
}
-
void
Machine::write_state(Redland::Model& model)
{
diff --git a/src/engine/MachineBuilder.cpp b/src/engine/MachineBuilder.cpp
index 629ce57..3bf9152 100644
--- a/src/engine/MachineBuilder.cpp
+++ b/src/engine/MachineBuilder.cpp
@@ -21,12 +21,12 @@
#include "raul/SharedPtr.hpp"
#include "raul/Quantizer.hpp"
-#include "machina/Edge.hpp"
#include "machina/Machine.hpp"
-#include "machina/MidiAction.hpp"
-#include "machina/Node.hpp"
+#include "Edge.hpp"
+#include "Node.hpp"
#include "MachineBuilder.hpp"
+#include "MidiAction.hpp"
using namespace std;
using namespace Raul;
diff --git a/src/engine/MidiAction.cpp b/src/engine/MidiAction.cpp
index e56202c..819e63b 100644
--- a/src/engine/MidiAction.cpp
+++ b/src/engine/MidiAction.cpp
@@ -16,11 +16,15 @@
*/
#include <iostream>
+
#include "raul/SharedPtr.hpp"
#include "raul/MIDISink.hpp"
#include "raul/Atom.hpp"
#include "raul/AtomRDF.hpp"
-#include "machina/MidiAction.hpp"
+
+#include "machina/types.hpp"
+
+#include "MidiAction.hpp"
namespace Machina {
diff --git a/src/engine/machina/MidiAction.hpp b/src/engine/MidiAction.hpp
index 73aed7b..f8b3fdc 100644
--- a/src/engine/machina/MidiAction.hpp
+++ b/src/engine/MidiAction.hpp
@@ -20,7 +20,9 @@
#include "raul/AtomicPtr.hpp"
#include "raul/TimeSlice.hpp"
-#include "types.hpp"
+
+#include "machina/types.hpp"
+
#include "Action.hpp"
namespace Raul { class MIDISink; }
diff --git a/src/engine/Mutation.cpp b/src/engine/Mutation.cpp
index c41b968..55d5715 100644
--- a/src/engine/Mutation.cpp
+++ b/src/engine/Mutation.cpp
@@ -18,12 +18,13 @@
#include <iostream>
#include <cstdlib>
-#include "machina/ActionFactory.hpp"
-#include "machina/Edge.hpp"
#include "machina/Machine.hpp"
-#include "machina/MidiAction.hpp"
#include "machina/Mutation.hpp"
+#include "ActionFactory.hpp"
+#include "Edge.hpp"
+#include "MidiAction.hpp"
+
using namespace std;
namespace Machina {
diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp
index e150a6f..b7eaf66 100644
--- a/src/engine/Node.cpp
+++ b/src/engine/Node.cpp
@@ -21,9 +21,12 @@
#include "raul/AtomRDF.hpp"
#include "redlandmm/World.hpp"
#include "redlandmm/Model.hpp"
-#include "machina/Node.hpp"
-#include "machina/Edge.hpp"
-#include "machina/ActionFactory.hpp"
+
+#include "machina/URIs.hpp"
+
+#include "ActionFactory.hpp"
+#include "Edge.hpp"
+#include "Node.hpp"
using namespace Raul;
using namespace std;
@@ -32,24 +35,24 @@ namespace Machina {
Node::Node(TimeDuration duration, bool initial)
- : _is_initial(initial)
+ : _enter_time(duration.unit())
+ , _duration(duration)
+ , _is_initial(initial)
, _is_selector(false)
, _is_active(false)
- , _enter_time(duration.unit())
- , _duration(duration)
{
}
Node::Node(const Node& copy)
: Stateful() // don't copy RDF ID
- , _is_initial(copy._is_initial)
- , _is_selector(copy._is_selector)
- , _is_active(false)
, _enter_time(copy._enter_time)
, _duration(copy._duration)
, _enter_action(ActionFactory::copy(copy._enter_action))
, _exit_action(ActionFactory::copy(copy._exit_action))
+ , _is_initial(copy._is_initial)
+ , _is_selector(copy._is_selector)
+ , _is_active(false)
{
for (Edges::const_iterator i = copy._edges.begin(); i != copy._edges.end(); ++i) {
SharedPtr<Edge> edge(new Edge(*i->get()));
@@ -187,20 +190,30 @@ Node::connected_to(SharedPtr<Node> node)
}
-void
-Node::remove_edges_to(SharedPtr<Node> node)
+SharedPtr<Edge>
+Node::remove_edge_to(SharedPtr<Node> node)
{
- for (Edges::iterator i = _edges.begin(); i != _edges.end() ; ) {
- Edges::iterator next = i;
- ++next;
-
- if ((*i)->head() == node)
+ for (Edges::iterator i = _edges.begin(); i != _edges.end(); ++i) {
+ if ((*i)->head() == node) {
+ SharedPtr<Edge> edge(*i);
_edges.erase(i);
-
- i = next;
+ edges_changed();
+ return edge;
+ }
}
- edges_changed();
+ return SharedPtr<Edge>();
+}
+
+
+void
+Node::set(URIInt key, const Raul::Atom& value)
+{
+ if (key == URIs::instance().machina_initial) {
+ set_initial(value.get_bool());
+ } else if (key == URIs::instance().machina_selector) {
+ set_selector(value.get_bool());
+ }
}
diff --git a/src/engine/machina/Node.hpp b/src/engine/Node.hpp
index 57f62f1..13f6bb3 100644
--- a/src/engine/machina/Node.hpp
+++ b/src/engine/Node.hpp
@@ -44,8 +44,6 @@ using Raul::TimeUnit;
*/
class Node : public Stateful {
public:
- typedef std::string ID;
-
Node(TimeDuration duration, bool initial=false);
Node(const Node& copy);
@@ -62,9 +60,10 @@ public:
void add_edge(SharedPtr<Edge> edge);
void remove_edge(SharedPtr<Edge> edge);
- void remove_edges_to(SharedPtr<Node> node);
+ SharedPtr<Edge> remove_edge_to(SharedPtr<Node> node);
bool connected_to(SharedPtr<Node> node);
+ void set(URIInt key, const Raul::Atom& value);
void write_state(Redland::Model& model);
bool is_initial() const { return _is_initial; }
@@ -72,7 +71,7 @@ public:
bool is_active() const { return _is_active; }
TimeStamp enter_time() const { assert(_is_active); return _enter_time; }
TimeStamp exit_time() const { assert(_is_active); return _enter_time + _duration; }
- TimeDuration duration() { return _duration; }
+ TimeDuration duration() const { return _duration; }
void set_duration(TimeDuration d) { _duration = d; }
bool is_selector() const { return _is_selector; }
void set_selector(bool i);
@@ -88,15 +87,15 @@ public:
private:
Node& operator=(const Node& other); // undefined
- Schrodinbit _changed;
- bool _is_initial;
- bool _is_selector;
- bool _is_active;
TimeStamp _enter_time; ///< valid iff _is_active
TimeDuration _duration;
SharedPtr<Action> _enter_action;
SharedPtr<Action> _exit_action;
Edges _edges;
+ Schrodinbit _changed;
+ bool _is_initial;
+ bool _is_selector;
+ bool _is_active;
};
diff --git a/src/engine/Problem.cpp b/src/engine/Problem.cpp
index ecd1c6b..bc32667 100644
--- a/src/engine/Problem.cpp
+++ b/src/engine/Problem.cpp
@@ -23,13 +23,15 @@
#include <iostream>
#include "eugene/Problem.hpp"
-#include "machina/ActionFactory.hpp"
+
#include "machina/Edge.hpp"
#include "machina/Machine.hpp"
+
#include "raul/SMFReader.hpp"
#include "raul/midi_events.h"
#include "machina-config.h"
+#include "ActionFactory.hpp"
#include "Problem.hpp"
using namespace std;
diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp
index b41ae49..3bf49c5 100644
--- a/src/engine/SMFDriver.cpp
+++ b/src/engine/SMFDriver.cpp
@@ -15,26 +15,30 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <list>
#include <iostream>
+#include <list>
+
#include <glibmm/convert.h>
+
#include "raul/Quantizer.hpp"
#include "raul/SharedPtr.hpp"
#include "raul/SMFWriter.hpp"
#include "raul/SMFReader.hpp"
+
#include "machina/Machine.hpp"
-#include "machina/Edge.hpp"
-#include "machina/SMFDriver.hpp"
+
+#include "Edge.hpp"
+#include "SMFDriver.hpp"
using namespace std;
namespace Machina {
-SMFDriver::SMFDriver(SharedPtr<Machine> machine)
- : Driver(machine)
+SMFDriver::SMFDriver(Raul::TimeUnit unit)
+ : Driver(SharedPtr<Machine>())
{
- _writer = SharedPtr<Raul::SMFWriter>(new Raul::SMFWriter(machine->time().unit()));
+ _writer = SharedPtr<Raul::SMFWriter>(new Raul::SMFWriter(unit));
}
@@ -144,7 +148,7 @@ SMFDriver::run(SharedPtr<Machine> machine, Raul::TimeStamp max_time)
Raul::TimeSlice time(machine->time().unit().ppt(), _writer->unit().ppt(), 120.0);
time.set_slice(TimeStamp(max_time.unit(), 0, 0), time.beats_to_ticks(max_time));
machine->set_sink(shared_from_this());
- machine->run(time);
+ machine->run(time, SharedPtr<UpdateBuffer>());
}
diff --git a/src/engine/machina/SMFDriver.hpp b/src/engine/SMFDriver.hpp
index a10442d..7081dc2 100644
--- a/src/engine/machina/SMFDriver.hpp
+++ b/src/engine/SMFDriver.hpp
@@ -39,7 +39,7 @@ class Machine;
class SMFDriver : public Driver,
public boost::enable_shared_from_this<SMFDriver> {
public:
- SMFDriver(SharedPtr<Machine> machine = SharedPtr<Machine>());
+ SMFDriver(Raul::TimeUnit unit);
SharedPtr<Machine> learn(const std::string& filename,
double q,
diff --git a/src/engine/Stateful.cpp b/src/engine/Stateful.cpp
index 0e1e3ad..75a1158 100644
--- a/src/engine/Stateful.cpp
+++ b/src/engine/Stateful.cpp
@@ -15,14 +15,14 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "machina/Stateful.hpp"
+#include "Stateful.hpp"
namespace Machina {
uint64_t Stateful::_next_id = 1;
Stateful::Stateful()
- : _id(_next_id++)
+ : _id(next_id())
{
}
diff --git a/src/engine/machina/Stateful.hpp b/src/engine/Stateful.hpp
index f35c00a..08a1425 100644
--- a/src/engine/machina/Stateful.hpp
+++ b/src/engine/Stateful.hpp
@@ -23,19 +23,31 @@
#include "redlandmm/World.hpp"
#include "redlandmm/Model.hpp"
+#include "machina/types.hpp"
+
+namespace Raul { class Atom; }
+
namespace Machina {
+class URIs;
+
class Stateful {
public:
Stateful();
virtual ~Stateful() {}
+ virtual void set(URIInt key, const Raul::Atom& value) {}
virtual void write_state(Redland::Model& model) = 0;
uint64_t id() const { return _id; }
const Redland::Node& rdf_id(Redland::World& world) const;
+ static uint64_t next_id() { return _next_id++; }
+
+protected:
+ Stateful(uint64_t id) : _id(id) {}
+
private:
static uint64_t _next_id;
@@ -43,6 +55,13 @@ private:
mutable Redland::Node _rdf_id;
};
+class StatefulKey : public Stateful {
+public:
+ StatefulKey(uint64_t id) : Stateful(id) {}
+
+ void write_state(Redland::Model& model) {}
+};
+
} // namespace Machina
#endif // MACHINA_STATEFUL_HPP
diff --git a/src/engine/machina/Driver.hpp b/src/engine/machina/Driver.hpp
index f850d3d..814f041 100644
--- a/src/engine/machina/Driver.hpp
+++ b/src/engine/machina/Driver.hpp
@@ -19,12 +19,14 @@
#define MACHINA_DRIVER_HPP
#include "raul/MIDISink.hpp"
+#include "raul/RingBuffer.hpp"
+
+#include "machina/types.hpp"
namespace Machina {
class Machine;
-
class Driver : public Raul::MIDISink {
public:
Driver(SharedPtr<Machine> machine) : _machine(machine) {}
@@ -33,9 +35,13 @@ public:
SharedPtr<Machine> machine() { return _machine; }
virtual void set_machine(SharedPtr<Machine> machine) { _machine = machine; }
+ SharedPtr<UpdateBuffer> update_sink() { return _updates; }
+ void set_update_sink(SharedPtr<UpdateBuffer> b) { _updates = b; }
+
virtual void set_bpm(double bpm) = 0;
virtual void set_quantization(double q) = 0;
+ virtual bool is_activated() const { return false; }
virtual void activate() {}
virtual void deactivate() {}
@@ -46,7 +52,8 @@ public:
virtual void finish_record() {}
protected:
- SharedPtr<Machine> _machine;
+ SharedPtr<Machine> _machine;
+ SharedPtr<UpdateBuffer> _updates;
};
diff --git a/src/engine/machina/Engine.hpp b/src/engine/machina/Engine.hpp
index 17d555d..022a2ca 100644
--- a/src/engine/machina/Engine.hpp
+++ b/src/engine/machina/Engine.hpp
@@ -34,12 +34,7 @@ class Machine;
class Engine {
public:
- Engine(SharedPtr<Driver> driver, Redland::World& rdf_world)
- : _driver(driver)
- , _rdf_world(rdf_world)
- , _loader(_rdf_world)
- {
- }
+ Engine(SharedPtr<Driver> driver, Redland::World& rdf_world);
Redland::World& rdf_world() { return _rdf_world; }
@@ -50,8 +45,14 @@ public:
SharedPtr<Machine> machine() { return _driver->machine(); }
SharedPtr<Machine> load_machine(const Glib::ustring& uri);
- SharedPtr<Machine> import_machine(const Glib::ustring& uri);
- SharedPtr<Machine> import_midi(const Glib::ustring& uri, double q, Raul::TimeDuration d);
+ SharedPtr<Machine> load_machine_midi(const Glib::ustring& uri,
+ double q,
+ Raul::TimeDuration dur);
+
+ void import_machine(SharedPtr<Machine> machine);
+
+ void export_midi(const Glib::ustring& filename,
+ Raul::TimeDuration dur);
void set_bpm(double bpm);
void set_quantization(double beat_fraction);
diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp
index e1a0f25..f3469c7 100644
--- a/src/engine/machina/Machine.hpp
+++ b/src/engine/machina/Machine.hpp
@@ -23,6 +23,7 @@
#include "raul/List.hpp"
#include "raul/Maid.hpp"
+#include "raul/RingBuffer.hpp"
#include "raul/SharedPtr.hpp"
#include "raul/TimeSlice.hpp"
#include "raul/WeakPtr.hpp"
@@ -33,6 +34,7 @@
namespace Machina {
+class Controller;
class LearnRequest;
/** A (Finite State) Machine.
@@ -63,7 +65,7 @@ public:
// Audio context
void reset(Raul::TimeStamp time);
- uint32_t run(const Raul::TimeSlice& time);
+ uint32_t run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates);
// Any context
inline Raul::TimeStamp time() const { return _time; }
@@ -84,8 +86,8 @@ private:
// Audio context
SharedPtr<Node> earliest_node() const;
- bool enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node);
- void exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node>);
+ bool enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates);
+ void exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node>, SharedPtr<UpdateBuffer> updates);
static const size_t MAX_ACTIVE_NODES = 128;
std::vector< SharedPtr<Node> > _active_nodes;
diff --git a/src/engine/machina/types.hpp b/src/engine/machina/types.hpp
index c39b682..74410d9 100644
--- a/src/engine/machina/types.hpp
+++ b/src/engine/machina/types.hpp
@@ -18,10 +18,16 @@
#ifndef MACHINA_TYPES_HPP
#define MACHINA_TYPES_HPP
+#include "raul/RingBuffer.hpp"
+
namespace Machina {
typedef unsigned char byte;
+typedef Raul::RingBuffer UpdateBuffer;
+
+typedef uint32_t URIInt;
+
} // namespace Machina
#endif // MACHINA_TYPES_HPP
diff --git a/src/engine/wscript b/src/engine/wscript
index 35f1303..1566a72 100644
--- a/src/engine/wscript
+++ b/src/engine/wscript
@@ -5,6 +5,7 @@ def build(bld):
core_source = '''
Action.cpp
ActionFactory.cpp
+ Controller.cpp
Edge.cpp
Engine.cpp
JackDriver.cpp
@@ -18,6 +19,8 @@ def build(bld):
Recorder.cpp
SMFDriver.cpp
Stateful.cpp
+ Updates.cpp
+ URIs.cpp
'''
if bld.env['HAVE_EUGENE']:
core_source += '''
@@ -27,7 +30,7 @@ def build(bld):
obj = bld(features = 'cxx cxxshlib')
obj.source = core_source
obj.export_includes = ['.']
- obj.includes = ['.', '../..']
+ obj.includes = ['.', '..', '../..']
obj.name = 'libmachina_engine'
obj.target = 'machina_engine'
core_libs = 'GLIBMM GTHREAD RAUL REDLANDMM JACK'
diff --git a/src/gui/EdgeView.cpp b/src/gui/EdgeView.cpp
index 51b94be..725d685 100644
--- a/src/gui/EdgeView.cpp
+++ b/src/gui/EdgeView.cpp
@@ -15,13 +15,17 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <iomanip>
-#include <sstream>
#include "flowcanvas/Canvas.hpp"
-#include "machina/Edge.hpp"
+
+#include "machina/Controller.hpp"
+#include "machina/types.hpp"
+
#include "EdgeView.hpp"
+#include "MachinaCanvas.hpp"
+#include "MachinaGUI.hpp"
#include "NodeView.hpp"
+using Machina::URIs;
/* probability colour stuff */
@@ -59,61 +63,73 @@ inline static uint32_t edge_color(float prob)
using namespace FlowCanvas;
-EdgeView::EdgeView(SharedPtr<Canvas> canvas,
- SharedPtr<NodeView> src,
- SharedPtr<NodeView> dst,
- SharedPtr<Machina::Edge> edge)
+EdgeView::EdgeView(SharedPtr<Canvas> canvas,
+ SharedPtr<NodeView> src,
+ SharedPtr<NodeView> dst,
+ SharedPtr<Machina::Client::ClientObject> edge)
: FlowCanvas::Connection(canvas, src, dst, 0x9FA0A0F4, true)
, _edge(edge)
{
- set_color(edge_color(_edge->probability()));
+ set_color(edge_color(probability()));
set_handle_style(HANDLE_CIRCLE);
show_handle(true);
+
+ edge->signal_property.connect(
+ sigc::mem_fun(this, &EdgeView::on_property));
}
-double
-EdgeView::length_hint() const
+float
+EdgeView::probability() const
{
- return _edge->tail().lock()->duration().ticks() * 10;
+ return _edge->get(URIs::instance().machina_probability).get_float();
}
-void
-EdgeView::show_label(bool show)
+double
+EdgeView::length_hint() const
{
- show_handle(show);
- set_color(edge_color(_edge->probability()));
+ SharedPtr<NodeView> tail = PtrCast<NodeView>(source().lock());
+ return tail->node()->get(URIs::instance().machina_duration).get_float() * 10.0;
}
void
-EdgeView::update()
+EdgeView::show_label(bool show)
{
- if (_handle)
- show_handle(true);
- set_color(edge_color(_edge->probability()));
+ show_handle(show);
+ set_color(edge_color(probability()));
}
bool
EdgeView::on_event(GdkEvent* ev)
{
+ SharedPtr<MachinaCanvas> canvas = PtrCast<MachinaCanvas>(_canvas.lock());
if (ev->type == GDK_BUTTON_PRESS) {
if (ev->button.state & GDK_CONTROL_MASK) {
if (ev->button.button == 1) {
- _edge->set_probability(_edge->probability() - 0.1);
- update();
+ canvas->app()->controller()->set_property(
+ _edge->id(),
+ URIs::instance().machina_probability,
+ Raul::Atom(probability() - 0.1f));
return true;
} else if (ev->button.button == 3) {
- _edge->set_probability(_edge->probability() + 0.1);
- update();
+ canvas->app()->controller()->set_property(
+ _edge->id(),
+ URIs::instance().machina_probability,
+ Raul::Atom(probability() + 0.1f));
return true;
}
}
}
-
return false;
}
+void
+EdgeView::on_property(Machina::URIInt key, const Raul::Atom& value)
+{
+ if (key == URIs::instance().machina_probability)
+ set_color(edge_color(value.get_float()));
+}
diff --git a/src/gui/EdgeView.hpp b/src/gui/EdgeView.hpp
index ea49b27..d9ffe71 100644
--- a/src/gui/EdgeView.hpp
+++ b/src/gui/EdgeView.hpp
@@ -15,32 +15,38 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_EDGEVIEW_H
-#define MACHINA_EDGEVIEW_H
+#ifndef MACHINA_EDGEVIEW_HPP
+#define MACHINA_EDGEVIEW_HPP
#include "flowcanvas/Connection.hpp"
-namespace Machina { class Edge; }
-class NodeView;
+#include "client/ClientObject.hpp"
+
+#include "machina/types.hpp"
+class NodeView;
-class EdgeView : public FlowCanvas::Connection {
+class EdgeView
+ : public FlowCanvas::Connection
+ , public Machina::Client::ClientObject::View {
public:
- EdgeView(SharedPtr<FlowCanvas::Canvas> canvas,
- SharedPtr<NodeView> src,
- SharedPtr<NodeView> dst,
- SharedPtr<Machina::Edge> edge);
+ EdgeView(SharedPtr<FlowCanvas::Canvas> canvas,
+ SharedPtr<NodeView> src,
+ SharedPtr<NodeView> dst,
+ SharedPtr<Machina::Client::ClientObject> edge);
void show_label(bool show);
- void update();
virtual double length_hint() const;
private:
bool on_event(GdkEvent* ev);
+ void on_property(Machina::URIInt key, const Raul::Atom& value);
+
+ float probability() const;
- SharedPtr<Machina::Edge> _edge;
+ SharedPtr<Machina::Client::ClientObject> _edge;
};
-#endif // MACHINA_EDGEVIEW_H
+#endif // MACHINA_EDGEVIEW_HPP
diff --git a/src/gui/GladeXml.hpp b/src/gui/GladeXml.hpp
index 36223db..cb54806 100644
--- a/src/gui/GladeXml.hpp
+++ b/src/gui/GladeXml.hpp
@@ -16,9 +16,12 @@
*/
#include <fstream>
+#include <iostream>
#include <string>
+
#include <gtkmm.h>
#include <libglademm/xml.h>
+
#include "machina-config.h"
class GladeXml
diff --git a/src/gui/MachinaCanvas.cpp b/src/gui/MachinaCanvas.cpp
index 3cf3e28..d3e42bf 100644
--- a/src/gui/MachinaCanvas.cpp
+++ b/src/gui/MachinaCanvas.cpp
@@ -17,14 +17,14 @@
#include <map>
+#include "raul/log.hpp"
#include "raul/SharedPtr.hpp"
#include "raul/TimeStamp.hpp"
-#include "machina/Action.hpp"
-#include "machina/Edge.hpp"
#include "machina/Engine.hpp"
-#include "machina/Machine.hpp"
-#include "machina/Node.hpp"
+#include "machina/Controller.hpp"
+#include "client/ClientObject.hpp"
+#include "client/ClientModel.hpp"
#include "EdgeView.hpp"
#include "MachinaCanvas.hpp"
@@ -33,7 +33,7 @@
using namespace Raul;
using namespace FlowCanvas;
-
+using namespace Machina;
MachinaCanvas::MachinaCanvas(MachinaGUI* app, int width, int height)
: Canvas(width, height)
@@ -43,7 +43,6 @@ MachinaCanvas::MachinaCanvas(MachinaGUI* app, int width, int height)
grab_focus();
}
-
void
MachinaCanvas::node_clicked(WeakPtr<NodeView> item, GdkEventButton* event)
{
@@ -54,19 +53,19 @@ MachinaCanvas::node_clicked(WeakPtr<NodeView> item, GdkEventButton* event)
if (event->state & GDK_CONTROL_MASK)
return;
- // Middle click, learn
- if (event->button == 2) {
- _app->engine()->machine()->learn(_app->maid(), node->node());
+ if (event->button == 2) { // Middle click: learn
+ _app->controller()->learn(_app->maid(), node->node()->id());
return;
- } else if (event->button == 3) {
+
+ } else if (event->button == 3) { // Right click: connect/disconnect
SharedPtr<NodeView> last = _last_clicked.lock();
if (last) {
if (node != last) {
if (get_connection(last, node))
- disconnect_node(last, node);
+ action_disconnect(last, node);
else
- connect_node(last, node);
+ action_connect(last, node);
}
last->set_default_base_color();
@@ -79,38 +78,14 @@ MachinaCanvas::node_clicked(WeakPtr<NodeView> item, GdkEventButton* event)
}
}
-
bool
MachinaCanvas::canvas_event(GdkEvent* event)
{
- static int last = 0;
-
- SharedPtr<Machina::Machine> machine = _app->engine()->machine();
- if (!machine)
- return false;
-
if (event->type == GDK_BUTTON_RELEASE
&& event->button.button == 3
&& !(event->button.state & (GDK_CONTROL_MASK))) {
- const double x = event->button.x;
- const double y = event->button.y;
-
- string name = string("Note")+(char)(last++ +'0');
-
- TimeDuration dur(machine->time().unit(), 1.0);
- SharedPtr<Machina::Node> node(new Machina::Node(dur, false));
- SharedPtr<NodeView> view(new NodeView(_app->window(), shared_from_this(), node,
- name, x, y));
-
- view->signal_clicked.connect(sigc::bind<0>(sigc::mem_fun(this,
- &MachinaCanvas::node_clicked), WeakPtr<NodeView>(view)));
- add_item(view);
- view->resize();
- view->raise_to_top();
-
- machine->add_node(node);
-
+ action_create_node(event->button.x, event->button.y);
return true;
} else {
@@ -118,101 +93,90 @@ MachinaCanvas::canvas_event(GdkEvent* event)
}
}
-
-void
-MachinaCanvas::connect_node(boost::shared_ptr<NodeView> src,
- boost::shared_ptr<NodeView> head)
-{
- SharedPtr<Machina::Edge> edge(new Machina::Edge(src->node(), head->node()));
- src->node()->add_edge(edge);
-
- boost::shared_ptr<Connection> c(new EdgeView(shared_from_this(),
- src, head, edge));
- src->add_connection(c);
- head->add_connection(c);
- add_connection(c);
-}
-
-
void
-MachinaCanvas::disconnect_node(boost::shared_ptr<NodeView> src,
- boost::shared_ptr<NodeView> head)
+MachinaCanvas::on_new_object(SharedPtr<Client::ClientObject> object)
{
- src->node()->remove_edges_to(head->node());
- remove_connection(src, head);
-}
+ const Machina::URIs& uris = URIs::instance();
+ const Raul::Atom& type = object->get(uris.rdf_type);
+ if (type == "machina:Node") {
+ SharedPtr<NodeView> view(
+ new NodeView(_app->window(), shared_from_this(), object,
+ object->get(uris.machina_canvas_x).get_float(),
+ object->get(uris.machina_canvas_y).get_float()));
+
+ //if ( ! node->enter_action() && ! node->exit_action() )
+ // view->set_base_color(0x101010FF);
+
+ view->signal_clicked.connect(
+ sigc::bind<0>(sigc::mem_fun(this, &MachinaCanvas::node_clicked),
+ WeakPtr<NodeView>(view)));
+
+ object->set_view(view);
+ add_item(view);
+ } else if (type == "machina:Edge") {
+ SharedPtr<Machina::Client::ClientObject> tail = _app->client_model()->find(
+ object->get(uris.machina_tail_id).get_int32());
+ SharedPtr<Machina::Client::ClientObject> head = _app->client_model()->find(
+ object->get(uris.machina_head_id).get_int32());
-SharedPtr<NodeView>
-MachinaCanvas::create_node_view(SharedPtr<Machina::Node> node)
-{
- SharedPtr<NodeView> view(new NodeView(_app->window(), shared_from_this(), node,
- "", 10, 10));
+ SharedPtr<NodeView> tail_view = PtrCast<NodeView>(tail->view());
+ SharedPtr<NodeView> head_view = PtrCast<NodeView>(head->view());
- if ( ! node->enter_action() && ! node->exit_action() )
- view->set_base_color(0x101010FF);
+ SharedPtr<EdgeView> view(
+ new EdgeView(shared_from_this(), tail_view, head_view, object));
- view->signal_clicked.connect(sigc::bind<0>(sigc::mem_fun(this,
- &MachinaCanvas::node_clicked), WeakPtr<NodeView>(view)));
+ tail_view->add_connection(view);
+ head_view->add_connection(view);
- add_item(view);
+ object->set_view(view);
+ add_connection(view);
- return view;
+ } else {
+ Raul::error << "Unknown object type " << type << std::endl;
+ }
}
-
void
-MachinaCanvas::build(SharedPtr<const Machina::Machine> machine, bool show_labels)
+MachinaCanvas::on_erase_object(SharedPtr<Client::ClientObject> object)
{
- destroy();
- _last_clicked.reset();
- assert(_items.empty());
-
- if (!machine)
- return;
-
- std::map<SharedPtr<Machina::Node>, SharedPtr<NodeView> > views;
-
- for (Machina::Machine::Nodes::const_iterator i = machine->nodes().begin();
- i != machine->nodes().end(); ++i) {
-
- const SharedPtr<NodeView> view = create_node_view(*i);
- views.insert(std::make_pair((*i), view));
- }
-
- for (ItemList::iterator i = _items.begin(); i != _items.end(); ++i) {
- const SharedPtr<NodeView> view = PtrCast<NodeView>(*i);
- if (!view)
- continue;
-
- for (Machina::Node::Edges::const_iterator e = view->node()->edges().begin();
- e != view->node()->edges().end(); ++e) {
-
- SharedPtr<NodeView> head_view = views[(*e)->head()];
- if (!head_view) {
- cerr << "WARNING: Edge to node with no view" << endl;
- continue;
- }
-
- boost::shared_ptr<Connection> c(new EdgeView(shared_from_this(),
- view, head_view, (*e)));
- view->add_connection(c);
- head_view->add_connection(c);
- add_connection(c);
+ const Raul::Atom& type = object->get(URIs::instance().rdf_type);
+ if (type == "machina:Node") {
+ SharedPtr<NodeView> view = PtrCast<NodeView>(object->view());
+ if (view) {
+ remove_item(view);
+ }
+ } else if (type == "machina:Edge") {
+ SharedPtr<EdgeView> view = PtrCast<EdgeView>(object->view());
+ if (view) {
+ remove_connection(view->source().lock(), view->dest().lock());
}
+ } else {
+ Raul::error << "Unknown object type " << type << std::endl;
}
-
- arrange();
}
+void
+MachinaCanvas::action_create_node(double x, double y)
+{
+ Machina::Client::ClientObject obj(0);
+ obj.set(URIs::instance().rdf_type, "machina:Node");
+ obj.set(URIs::instance().machina_canvas_x, Raul::Atom((float)x));
+ obj.set(URIs::instance().machina_canvas_y, Raul::Atom((float)y));
+ obj.set(URIs::instance().machina_duration, Raul::Atom((float)1.0));
+ _app->controller()->create(obj);
+}
void
-MachinaCanvas::update_edges()
+MachinaCanvas::action_connect(boost::shared_ptr<NodeView> src,
+ boost::shared_ptr<NodeView> head)
{
- for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
- SharedPtr<EdgeView> edge = PtrCast<EdgeView>(*i);
- if (edge)
- edge->update();
- }
+ _app->controller()->connect(src->node()->id(), head->node()->id());
}
+void
+MachinaCanvas::action_disconnect(boost::shared_ptr<NodeView> src,
+ boost::shared_ptr<NodeView> head)
+{
+ _app->controller()->disconnect(src->node()->id(), head->node()->id());
+}
diff --git a/src/gui/MachinaCanvas.hpp b/src/gui/MachinaCanvas.hpp
index b358638..dc23505 100644
--- a/src/gui/MachinaCanvas.hpp
+++ b/src/gui/MachinaCanvas.hpp
@@ -15,8 +15,8 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_CANVAS_HPP_H
-#define MACHINA_CANVAS_HPP_H
+#ifndef MACHINA_CANVAS_HPP_HPP
+#define MACHINA_CANVAS_HPP_HPP
#include <string>
#include "raul/SharedPtr.hpp"
@@ -28,30 +28,38 @@ using namespace FlowCanvas;
class MachinaGUI;
class NodeView;
+namespace Machina { namespace Client { class ClientObject; } }
class MachinaCanvas : public Canvas
{
public:
MachinaCanvas(MachinaGUI* app, int width, int height);
- void connect_node(SharedPtr<NodeView> port1,
- SharedPtr<NodeView> port2);
+ //void build(SharedPtr<const Machina::Machine> machine, bool show_labels);
+ //void update_edges();
- void disconnect_node(SharedPtr<NodeView> port1,
- SharedPtr<NodeView> port2);
-
- void build(SharedPtr<const Machina::Machine> machine, bool show_labels);
- void update_edges();
+ void on_new_object(SharedPtr<Machina::Client::ClientObject> object);
+ void on_erase_object(SharedPtr<Machina::Client::ClientObject> object);
ArtVpathDash* selector_dash() { return _selector_dash; }
+ MachinaGUI* app() { return _app; }
+
protected:
bool canvas_event(GdkEvent* event);
void node_clicked(WeakPtr<NodeView> item, GdkEventButton* ev);
private:
- SharedPtr<NodeView> create_node_view(SharedPtr<Machina::Node> node);
+ //SharedPtr<NodeView> create_node_view(SharedPtr<Machina::Node> node);
+
+ void action_create_node(double x, double y);
+
+ void action_connect(SharedPtr<NodeView> port1,
+ SharedPtr<NodeView> port2);
+
+ void action_disconnect(SharedPtr<NodeView> port1,
+ SharedPtr<NodeView> port2);
MachinaGUI* _app;
ArtVpathDash* _selector_dash;
@@ -59,4 +67,4 @@ private:
};
-#endif // MACHINA_CANVAS_HPP_H
+#endif // MACHINA_CANVAS_HPP_HPP
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp
index 5aa5116..83ae23b 100644
--- a/src/gui/MachinaGUI.cpp
+++ b/src/gui/MachinaGUI.cpp
@@ -25,10 +25,12 @@
#include <libgnomecanvasmm.h>
#include <libglademm/xml.h>
#include "redlandmm/Model.hpp"
+#include "machina/Controller.hpp"
#include "machina/Engine.hpp"
#include "machina/Machine.hpp"
#include "machina/Mutation.hpp"
-#include "machina/SMFDriver.hpp"
+#include "machina/Updates.hpp"
+#include "client/ClientModel.hpp"
#include "GladeXml.hpp"
#include "MachinaGUI.hpp"
#include "MachinaCanvas.hpp"
@@ -47,6 +49,8 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
, _evolve(false)
, _unit(TimeUnit::BEATS, 19200)
, _engine(engine)
+ , _client_model(new Machina::Client::ClientModel())
+ , _controller(new Machina::Controller(_engine, *_client_model.get()))
, _maid(new Raul::Maid(32))
{
_canvas = boost::shared_ptr<MachinaCanvas>(new MachinaCanvas(this, 1600*2, 1200*2));
@@ -190,7 +194,11 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
_evolve_toolbar->set_sensitive(false);
#endif
- _canvas->build(engine->machine(), _menu_view_labels->get_active());
+ _controller->announce(engine->machine());
+ _canvas->arrange();
+
+ _client_model->signal_new_object.connect(sigc::mem_fun(this, &MachinaGUI::on_new_object));
+ _client_model->signal_erase_object.connect(sigc::mem_fun(this, &MachinaGUI::on_erase_object));
}
@@ -218,14 +226,7 @@ MachinaGUI::evolve_callback()
bool
MachinaGUI::idle_callback()
{
- const bool show_labels = _menu_view_labels->get_active();
-
- for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) {
- const SharedPtr<NodeView> nv = PtrCast<NodeView>(*i);
- if (nv && nv->node()->changed())
- nv->update_state(show_labels);
- }
-
+ _controller->process_updates();
return true;
}
@@ -239,12 +240,12 @@ MachinaGUI::scrolled_window_event(GdkEvent* event)
ItemList selection = _canvas->selected_items();
_canvas->clear_selection();
- for (ItemList::iterator i = selection.begin();
- i != selection.end(); ++i) {
+ for (ItemList::iterator i = selection.begin(); i != selection.end(); ++i) {
SharedPtr<NodeView> view = PtrCast<NodeView>(*i);
if (view) {
- _engine->machine()->remove_node(view->node());
- _canvas->remove_item(view);
+ _controller->erase(view->node()->id());
+ //_engine->machine()->remove_node(view->node());
+ //_canvas->remove_item(view);
}
}
@@ -320,6 +321,7 @@ MachinaGUI::random_mutation(SharedPtr<Machine> machine)
void
MachinaGUI::mutate(SharedPtr<Machine> machine, unsigned mutation)
{
+ #if 0
if (!machine)
machine = _engine->machine();
@@ -356,6 +358,7 @@ MachinaGUI::mutate(SharedPtr<Machine> machine, unsigned mutation)
break;
default: throw;
}
+ #endif
}
@@ -428,10 +431,11 @@ MachinaGUI::menu_file_open()
const int result = dialog.run();
if (result == Gtk::RESPONSE_OK) {
- SharedPtr<Machina::Machine> new_machine = _engine->import_machine(dialog.get_uri());
+ SharedPtr<Machina::Machine> new_machine = _engine->load_machine(dialog.get_uri());
if (new_machine) {
_canvas->destroy();
- _canvas->build(new_machine, _menu_view_labels->get_active());
+ _controller->announce(new_machine);
+ _canvas->arrange();
_save_uri = dialog.get_uri();
}
}
@@ -537,19 +541,19 @@ MachinaGUI::menu_import_midi()
const int result = dialog.run();
if (result == Gtk::RESPONSE_OK) {
- SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver());
-
- double length_dbl = length_sb->get_value_as_int();
- Raul::TimeStamp length(_unit, length_dbl);
+ const double length_dbl = length_sb->get_value_as_int();
+ const Raul::TimeStamp length(_unit, length_dbl);
- SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_filename(), 0.0, length);
+ SharedPtr<Machina::Machine> machine = _engine->load_machine_midi(
+ dialog.get_filename(), 0.0, length);
if (machine) {
dialog.hide();
machine->activate();
machine->reset(machine->time());
- _canvas->build(machine, _menu_view_labels->get_active());
+ //_canvas->build(machine, _menu_view_labels->get_active());
_engine->driver()->set_machine(machine);
+ _controller->announce(machine);
} else {
Gtk::MessageDialog msg_dialog(dialog, "Error loading MIDI file",
false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
@@ -572,19 +576,23 @@ MachinaGUI::menu_export_midi()
filt.set_name("MIDI Files");
dialog.set_filter(filt);
+ Gtk::HBox* extra_widget = Gtk::manage(new Gtk::HBox());
+ Gtk::SpinButton* dur_sb = Gtk::manage(new Gtk::SpinButton());
+ dur_sb->set_increments(1, 10);
+ dur_sb->set_range(0, INT_MAX);
+ dur_sb->set_value(0);
+ extra_widget->pack_start(*Gtk::manage(new Gtk::Label("")), true, true);
+ extra_widget->pack_start(*Gtk::manage(new Gtk::Label("Duration (beats): ")), false, false);
+ extra_widget->pack_start(*dur_sb, false, false);
+ dialog.set_extra_widget(*extra_widget);
+ extra_widget->show_all();
+
const int result = dialog.run();
if (result == Gtk::RESPONSE_OK) {
- SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver());
- _engine->driver()->deactivate();
- const SharedPtr<Machina::Machine> m = _engine->machine();
- m->set_sink(file_driver->writer());
- file_driver->writer()->start(dialog.get_filename(), TimeStamp(_unit, 0.0));
- file_driver->run(m, TimeStamp(_unit, 32.0)); // TODO: solve halting problem
- m->set_sink(_engine->driver());
- m->reset(m->time());
- file_driver->writer()->finish();
- _engine->driver()->activate();
+ const double dur_dbl = dur_sb->get_value_as_int();
+ const Raul::TimeStamp dur(_unit, dur_dbl);
+ _engine->export_midi(dialog.get_filename(), dur);
}
}
@@ -658,7 +666,7 @@ MachinaGUI::record_toggled()
_engine->driver()->start_record(_step_record_checkbutton->get_active());
} else if (_engine->driver()->recording()) {
_engine->driver()->finish_record();
- _canvas->build(_engine->machine(), _menu_view_labels->get_active());
+ //_canvas->build(_engine->machine(), _menu_view_labels->get_active());
update_toolbar();
}
}
@@ -672,7 +680,7 @@ MachinaGUI::stop_clicked()
if (_engine->driver()->recording()) {
_engine->driver()->stop();
_engine->machine()->deactivate();
- _canvas->build(_engine->machine(), _menu_view_labels->get_active());
+ //_canvas->build(_engine->machine(), _menu_view_labels->get_active());
} else {
_engine->driver()->stop();
_engine->machine()->deactivate();
@@ -691,4 +699,14 @@ MachinaGUI::play_toggled()
_engine->machine()->deactivate();
}
+void
+MachinaGUI::on_new_object(SharedPtr<Client::ClientObject> object)
+{
+ _canvas->on_new_object(object);
+}
+void
+MachinaGUI::on_erase_object(SharedPtr<Client::ClientObject> object)
+{
+ _canvas->on_erase_object(object);
+}
diff --git a/src/gui/MachinaGUI.hpp b/src/gui/MachinaGUI.hpp
index 75fdafd..58dc48f 100644
--- a/src/gui/MachinaGUI.hpp
+++ b/src/gui/MachinaGUI.hpp
@@ -15,18 +15,27 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_GUI_H
-#define MACHINA_GUI_H
+#ifndef MACHINA_GUI_HPP
+#define MACHINA_GUI_HPP
#include <string>
#include <libgnomecanvasmm.h>
-#include "machina-config.h"
-#include "raul/SharedPtr.hpp"
+
#include "raul/Maid.hpp"
+#include "raul/SharedPtr.hpp"
+#include "raul/TimeStamp.hpp"
+
+#include "machina-config.h"
using namespace std;
-namespace Machina { class Machine; class Engine; class Evolver; }
+namespace Machina {
+class Machine;
+class Engine;
+class Evolver;
+class Controller;
+namespace Client { class ClientModel; class ClientObject; }
+}
class MachinaCanvas;
@@ -46,8 +55,15 @@ public:
void attach();
void quit() { _main_window->hide(); }
+ SharedPtr<Machina::Controller> controller() { return _controller; }
+
inline void queue_refresh() { _refresh = true; }
+ void on_new_object(SharedPtr<Machina::Client::ClientObject> object);
+ void on_erase_object(SharedPtr<Machina::Client::ClientObject> object);
+
+ SharedPtr<Machina::Client::ClientModel> client_model() { return _client_model; }
+
protected:
void connect_widgets();
@@ -93,9 +109,11 @@ protected:
Raul::TimeUnit _unit;
- boost::shared_ptr<MachinaCanvas> _canvas;
- boost::shared_ptr<Machina::Engine> _engine;
-
+ SharedPtr<MachinaCanvas> _canvas;
+ SharedPtr<Machina::Engine> _engine;
+ SharedPtr<Machina::Client::ClientModel> _client_model;
+ SharedPtr<Machina::Controller> _controller;
+
SharedPtr<Raul::Maid> _maid;
SharedPtr<Machina::Evolver> _evolver;
@@ -144,4 +162,4 @@ protected:
Gtk::ToolButton* _adjust_edge_button;
};
-#endif // MACHINA_GUI_H
+#endif // MACHINA_GUI_HPP
diff --git a/src/gui/NodePropertiesWindow.cpp b/src/gui/NodePropertiesWindow.cpp
index fe1ec81..b896902 100644
--- a/src/gui/NodePropertiesWindow.cpp
+++ b/src/gui/NodePropertiesWindow.cpp
@@ -16,8 +16,6 @@
*/
#include <string>
-#include "machina/MidiAction.hpp"
-#include "machina/ActionFactory.hpp"
#include "NodePropertiesWindow.hpp"
#include "GladeXml.hpp"
@@ -38,9 +36,13 @@ NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::
xml->get_widget("node_properties_apply_button", _apply_button);
xml->get_widget("node_properties_cancel_button", _cancel_button);
xml->get_widget("node_properties_ok_button", _ok_button);
-
- _apply_button->signal_clicked().connect(sigc::mem_fun(this, &NodePropertiesWindow::apply_clicked));
- _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &NodePropertiesWindow::cancel_clicked)); _ok_button->signal_clicked().connect(sigc::mem_fun(this, &NodePropertiesWindow::ok_clicked));
+
+ _apply_button->signal_clicked().connect(
+ sigc::mem_fun(this, &NodePropertiesWindow::apply_clicked));
+ _cancel_button->signal_clicked().connect(
+ sigc::mem_fun(this, &NodePropertiesWindow::cancel_clicked));
+ _ok_button->signal_clicked().connect(
+ sigc::mem_fun(this, &NodePropertiesWindow::ok_clicked));
}
@@ -52,6 +54,7 @@ NodePropertiesWindow::~NodePropertiesWindow()
void
NodePropertiesWindow::apply_clicked()
{
+ #if 0
const uint8_t note = _note_spinbutton->get_value();
if (!_node->enter_action()) {
_node->set_enter_action(ActionFactory::note_on(note));
@@ -67,6 +70,7 @@ NodePropertiesWindow::apply_clicked()
TimeStamp duration(TimeUnit(TimeUnit::BEATS, 19200), duration_dbl);
_node->set_duration(duration);
_node->set_changed();
+ #endif
}
@@ -88,9 +92,10 @@ NodePropertiesWindow::ok_clicked()
void
-NodePropertiesWindow::set_node(SharedPtr<Machina::Node> node)
+NodePropertiesWindow::set_node(SharedPtr<Machina::Client::ClientObject> node)
{
_node = node;
+ #if 0
SharedPtr<MidiAction> enter_action = PtrCast<MidiAction>(node->enter_action());
if (enter_action && enter_action->event_size() > 1
&& (enter_action->event()[0] & 0xF0) == 0x90) {
@@ -103,11 +108,12 @@ NodePropertiesWindow::set_node(SharedPtr<Machina::Node> node)
_note_spinbutton->hide();
}
_duration_spinbutton->set_value(node->duration().to_double());
+ #endif
}
void
-NodePropertiesWindow::present(Gtk::Window* parent, SharedPtr<Machina::Node> node)
+NodePropertiesWindow::present(Gtk::Window* parent, SharedPtr<Machina::Client::ClientObject> node)
{
if (!_instance) {
Glib::RefPtr<Gnome::Glade::Xml> xml = GladeXml::create();
diff --git a/src/gui/NodePropertiesWindow.hpp b/src/gui/NodePropertiesWindow.hpp
index f88978c..b56941e 100644
--- a/src/gui/NodePropertiesWindow.hpp
+++ b/src/gui/NodePropertiesWindow.hpp
@@ -15,24 +15,28 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NODEPROPERTIESWINDOW_H
-#define NODEPROPERTIESWINDOW_H
+#ifndef NODEPROPERTIESWINDOW_HPP
+#define NODEPROPERTIESWINDOW_HPP
#include <gtkmm.h>
+
#include <libglademm/xml.h>
-#include "machina/Node.hpp"
+
+#include <raul/SharedPtr.hpp>
+
+namespace Machina { namespace Client { class ClientObject; } }
class NodePropertiesWindow : public Gtk::Dialog
{
public:
- static void present(Gtk::Window* parent, SharedPtr<Machina::Node> node);
+ static void present(Gtk::Window* parent, SharedPtr<Machina::Client::ClientObject> node);
private:
friend class Gnome::Glade::Xml;
NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml);
~NodePropertiesWindow();
- void set_node(SharedPtr<Machina::Node> node);
+ void set_node(SharedPtr<Machina::Client::ClientObject> node);
void apply_clicked();
void cancel_clicked();
@@ -40,7 +44,7 @@ private:
static NodePropertiesWindow* _instance;
- SharedPtr<Machina::Node> _node;
+ SharedPtr<Machina::Client::ClientObject> _node;
Gtk::SpinButton* _note_spinbutton;
Gtk::SpinButton* _duration_spinbutton;
@@ -50,4 +54,4 @@ private:
};
-#endif // NODEPROPERTIESWINDOW_H
+#endif // NODEPROPERTIESWINDOW_HPP
diff --git a/src/gui/NodeView.cpp b/src/gui/NodeView.cpp
index 943c6f7..2810f99 100644
--- a/src/gui/NodeView.cpp
+++ b/src/gui/NodeView.cpp
@@ -1,5 +1,5 @@
/* This file is part of Machina.
- * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
+ * Copyright (C) 2007-2010 David Robillard <http://drobilla.net>
*
* Machina is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,29 +15,37 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <iostream>
-#include "machina/MidiAction.hpp"
-#include "NodeView.hpp"
+#include "machina/Controller.hpp"
+#include "machina/URIs.hpp"
+#include "machina/types.hpp"
+
+#include "client/ClientModel.hpp"
+
+#include "MachinaCanvas.hpp"
+#include "MachinaGUI.hpp"
#include "NodePropertiesWindow.hpp"
+#include "NodeView.hpp"
using namespace std;
-
-NodeView::NodeView(Gtk::Window* window,
- SharedPtr<FlowCanvas::Canvas> canvas,
- SharedPtr<Machina::Node> node,
- const std::string& name,
- double x,
- double y)
- : FlowCanvas::Ellipse(canvas, name, x, y, 20, 20, false)
+using Machina::URIs;
+
+NodeView::NodeView(Gtk::Window* window,
+ SharedPtr<FlowCanvas::Canvas> canvas,
+ SharedPtr<Machina::Client::ClientObject> node,
+ double x,
+ double y)
+ : FlowCanvas::Ellipse(canvas, "", x, y, 20, 20, false)
, _window(window)
, _node(node)
, _default_border_color(_border_color)
, _old_color(_color)
{
- signal_clicked.connect(sigc::mem_fun(this, &NodeView::handle_click));
- update_state(false);
-}
+ signal_clicked.connect(
+ sigc::mem_fun(this, &NodeView::handle_click));
+ node->signal_property.connect(
+ sigc::mem_fun(this, &NodeView::on_property));
+}
void
NodeView::on_double_click(GdkEventButton*)
@@ -45,24 +53,32 @@ NodeView::on_double_click(GdkEventButton*)
NodePropertiesWindow::present(_window, _node);
}
+bool
+NodeView::node_is(Machina::URIInt key)
+{
+ const Raul::Atom& value = _node->get(key);
+ return value.type() == Raul::Atom::BOOL && value.get_bool();
+}
void
NodeView::handle_click(GdkEventButton* event)
{
if (event->state & GDK_CONTROL_MASK) {
+ SharedPtr<MachinaCanvas> canvas = PtrCast<MachinaCanvas>(_canvas.lock());
if (event->button == 1) {
- bool is_initial = _node->is_initial();
- _node->set_initial( ! is_initial );
- update_state(_label != NULL);
+ canvas->app()->controller()->set_property(
+ _node->id(),
+ URIs::instance().machina_initial,
+ !node_is(URIs::instance().machina_initial));
} else if (event->button == 3) {
- bool is_selector = _node->is_selector();
- _node->set_selector( ! is_selector );
- update_state(_label != NULL);
+ canvas->app()->controller()->set_property(
+ _node->id(),
+ URIs::instance().machina_selector,
+ !node_is(URIs::instance().machina_selector));
}
}
}
-
static std::string
midi_note_name(uint8_t num)
{
@@ -79,23 +95,22 @@ midi_note_name(uint8_t num)
void
NodeView::show_label(bool show)
{
- SharedPtr<Machina::MidiAction> action
- = PtrCast<Machina::MidiAction>(_node->enter_action());
-
if (show) {
- if (action && action->event_size() > 1
- && (action->event()[0] & 0xF0) == 0x90) {
- const uint8_t note_num = action->event()[1];
- set_name(midi_note_name(note_num));
+ if (_enter_action) {
+ Raul::Atom note_number = _enter_action->get(URIs::instance().machina_note_number);
+ if (note_number.is_valid()) {
+ set_name(midi_note_name(note_number.get_int32()));
+ return;
+ }
}
- } else {
- set_name("");
}
+
+ set_name("");
}
-
/// Dash style for selector node outlines
-static ArtVpathDash* selector_dash()
+static ArtVpathDash*
+selector_dash()
{
static ArtVpathDash* selector_dash = NULL;
@@ -115,32 +130,45 @@ NodeView::set_selected(bool selected)
{
Ellipse::set_selected(selected);
if (!selected)
- _ellipse.property_dash() = _node->is_selector() ? selector_dash() : 0;
+ _ellipse.property_dash() = node_is(URIs::instance().machina_selector) ? selector_dash() : 0;
}
-
void
-NodeView::update_state(bool show_labels)
+NodeView::on_property(Machina::URIInt key, const Raul::Atom& value)
{
- static const uint32_t active_color = 0x408040FF;
+ static const uint32_t active_color = 0x408040FF;
static const uint32_t active_border_color = 0x00FF00FF;
- if (_node->is_active()) {
- if (_color != active_color) {
- _old_color = _color;
- set_base_color(active_color);
- set_border_color(active_border_color);
+ if (key == URIs::instance().machina_selector) {
+ _ellipse.property_dash() = value.get_bool() ? selector_dash() : 0;
+ } else if (key == URIs::instance().machina_initial) {
+ set_border_width(value.get_bool() ? 4.0 : 1.0);
+ } else if (key == URIs::instance().machina_active) {
+ if (value.get_bool()) {
+ if (_color != active_color) {
+ _old_color = _color;
+ set_base_color(active_color);
+ set_border_color(active_border_color);
+ }
+ } else if (_color == active_color) {
+ set_base_color(_old_color);
+ set_border_color(_default_border_color);
}
- } else if (_color == active_color) {
- set_base_color(_old_color);
- set_border_color(_default_border_color);
+ } else if (key == URIs::instance().machina_enter_action) {
+ const uint64_t action_id = value.get_int32();
+ SharedPtr<MachinaCanvas> canvas = PtrCast<MachinaCanvas>(_canvas.lock());
+ _enter_action_connection.disconnect();
+ _enter_action = canvas->app()->client_model()->find(action_id);
+ _enter_action_connection = _enter_action->signal_property.connect(
+ sigc::mem_fun(this, &NodeView::on_action_property));
+ } else {
+ cout << "Unknown property " << key << endl;
}
+}
- _ellipse.property_dash() = _node->is_selector() ? selector_dash() : 0;
-
- set_border_width(_node->is_initial() ? 4.0 : 1.0);
-
- if (show_labels)
+void
+NodeView::on_action_property(Machina::URIInt key, const Raul::Atom& value)
+{
+ if (key == URIs::instance().machina_note_number)
show_label(true);
}
-
diff --git a/src/gui/NodeView.hpp b/src/gui/NodeView.hpp
index 0de7d6f..a70e821 100644
--- a/src/gui/NodeView.hpp
+++ b/src/gui/NodeView.hpp
@@ -15,23 +15,26 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_NODEVIEW_H
-#define MACHINA_NODEVIEW_H
+#ifndef MACHINA_NODEVIEW_HPP
+#define MACHINA_NODEVIEW_HPP
#include "flowcanvas/Ellipse.hpp"
-#include "machina/Node.hpp"
+#include "client/ClientObject.hpp"
-class NodeView : public FlowCanvas::Ellipse {
+#include "machina/types.hpp"
+
+class NodeView
+ : public FlowCanvas::Ellipse
+ , public Machina::Client::ClientObject::View {
public:
- NodeView(Gtk::Window* window,
- SharedPtr<FlowCanvas::Canvas> canvas,
- SharedPtr<Machina::Node> node,
- const std::string& name,
- double x,
- double y);
+ NodeView(Gtk::Window* window,
+ SharedPtr<FlowCanvas::Canvas> canvas,
+ SharedPtr<Machina::Client::ClientObject> node,
+ double x,
+ double y);
- SharedPtr<Machina::Node> node() { return _node; }
+ SharedPtr<Machina::Client::ClientObject> node() { return _node; }
void show_label(bool show);
@@ -40,13 +43,20 @@ public:
private:
void handle_click(GdkEventButton* ev);
void on_double_click(GdkEventButton* ev);
+ void on_property(Machina::URIInt key, const Raul::Atom& value);
+ void on_action_property(Machina::URIInt key, const Raul::Atom& value);
void set_selected(bool selected);
- Gtk::Window* _window;
- SharedPtr<Machina::Node> _node;
- uint32_t _default_border_color;
- uint32_t _old_color;
+ bool node_is(Machina::URIInt key);
+
+ Gtk::Window* _window;
+ SharedPtr<Machina::Client::ClientObject> _node;
+ uint32_t _default_border_color;
+ uint32_t _old_color;
+
+ SharedPtr<Machina::Client::ClientObject> _enter_action;
+ sigc::connection _enter_action_connection;
};
-#endif // MACHINA_NODEVIEW_H
+#endif // MACHINA_NODEVIEW_HPP
diff --git a/src/gui/main.cpp b/src/gui/main.cpp
index 6f79c7d..a2fd12a 100644
--- a/src/gui/main.cpp
+++ b/src/gui/main.cpp
@@ -24,7 +24,7 @@
#include "machina/Engine.hpp"
#include "machina/Loader.hpp"
#include "machina/Machine.hpp"
-#include "machina/SMFDriver.hpp"
+#include "machina/URIs.hpp"
#include "MachinaGUI.hpp"
using namespace std;
@@ -39,6 +39,8 @@ main(int argc, char** argv)
Redland::World rdf_world;
+ Machina::URIs::init();
+
SharedPtr<Machina::Machine> machine;
// Load machine, if given
diff --git a/src/gui/wscript b/src/gui/wscript
index 634971e..2e0aa23 100644
--- a/src/gui/wscript
+++ b/src/gui/wscript
@@ -11,11 +11,11 @@ def build(bld):
NodeView.cpp
'''
- obj.includes = ['.', '../..', '../engine']
+ obj.includes = ['.', '..', '../..', '../engine']
obj.export_includes = ['.']
obj.name = 'libmachina_gui'
obj.target = 'machina_gui'
- obj.use = 'libmachina_engine'
+ obj.use = 'libmachina_engine libmachina_client'
autowaf.use_lib(bld, obj, '''
FLOWCANVAS
GLADEMM
diff --git a/src/machina.cpp b/src/machina.cpp
index 09c37f4..4e14992 100644
--- a/src/machina.cpp
+++ b/src/machina.cpp
@@ -24,7 +24,6 @@
#include "machina/Engine.hpp"
#include "machina/Machine.hpp"
#include "machina/MidiAction.hpp"
-#include "machina/Node.hpp"
#ifdef HAVE_EUGENE
#include "machina/Problem.hpp"
#endif
diff --git a/src/midi2machina.cpp b/src/midi2machina.cpp
index bea5497..1125f13 100644
--- a/src/midi2machina.cpp
+++ b/src/midi2machina.cpp
@@ -20,7 +20,6 @@
#include "redlandmm/Model.hpp"
#include "machina/Engine.hpp"
#include "machina/Machine.hpp"
-#include "machina/Node.hpp"
#include "machina/Action.hpp"
#include "machina/Edge.hpp"
#include "machina/SMFDriver.hpp"