aboutsummaryrefslogtreecommitdiffstats
path: root/src/engine/Machine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/Machine.cpp')
-rw-r--r--src/engine/Machine.cpp88
1 files changed, 62 insertions, 26 deletions
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index fbda9ad..1a9e3ae 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -31,7 +31,8 @@ namespace Machina {
Machine::Machine()
- : _is_activated(false)
+ : _active_nodes(MAX_ACTIVE_NODES, SharedPtr<Node>())
+ , _is_activated(false)
, _is_finished(false)
, _time(0)
{
@@ -45,22 +46,60 @@ Machine::Machine()
*/
Machine::Machine(const Machine& copy)
: Raul::Stateful() // don't copy RDF ID
+ , _active_nodes(MAX_ACTIVE_NODES, SharedPtr<Node>())
, _is_activated(false)
, _is_finished(false)
, _time(0)
, _sink(copy._sink)
{
- for (Nodes::const_iterator i = copy._nodes.begin(); i != copy._nodes.end(); ++i) {
- SharedPtr<Machina::Node> node(new Machina::Node(*i->get()));
+ map< SharedPtr<Node>, SharedPtr<Node> > replacements;
+
+ for (Nodes::const_iterator n = copy._nodes.begin(); n != copy._nodes.end(); ++n) {
+ SharedPtr<Machina::Node> node(new Machina::Node(*n->get()));
_nodes.push_back(node);
+ replacements[*n] = node;
+ }
+
+ for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
+ for (Node::Edges::const_iterator e = (*n)->edges().begin(); e != (*n)->edges().end(); ++e) {
+ (*e)->set_tail(*n);
+ (*e)->set_head(replacements[(*e)->head()]);
+ assert((*e)->head());
+ }
}
}
-
-Machine::~Machine()
+
+Machine&
+Machine::operator=(const Machine& other)
{
-}
+ _active_nodes = std::vector< SharedPtr<Node> >(MAX_ACTIVE_NODES, SharedPtr<Node>());
+ _is_activated = false;
+ _is_finished = false;
+ _time = 0;
+ _pending_learn = SharedPtr<LearnRequest>();
+ _sink = other._sink;
+ _nodes.clear();
+
+ map< SharedPtr<Node>, SharedPtr<Node> > replacements;
+
+ for (Nodes::const_iterator n = other._nodes.begin(); n != other._nodes.end(); ++n) {
+ SharedPtr<Machina::Node> node(new Machina::Node(*n->get()));
+ _nodes.push_back(node);
+ replacements[*n] = node;
+ }
+ for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
+ for (Node::Edges::const_iterator e = (*n)->edges().begin(); e != (*n)->edges().end(); ++e) {
+ (*e)->set_tail(*n);
+ (*e)->set_head(replacements[(*e)->head()]);
+ assert((*e)->head());
+ }
+ }
+
+ return *this;
+}
+
/** Set the MIDI sink to be used for executing MIDI actions.
*
@@ -128,13 +167,12 @@ Machine::remove_node(SharedPtr<Node> node)
void
Machine::reset(Raul::BeatTime time)
{
- for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) {
- _active_nodes[i].reset();
- }
+ for (size_t i=0; i < MAX_ACTIVE_NODES; ++i)
+ _active_nodes.at(i).reset();
if (!_is_finished) {
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
- const SharedPtr<Node> node = (*n);
+ SharedPtr<Node> node = (*n);
if (node->is_active())
node->exit(_sink.lock(), time);
@@ -156,7 +194,7 @@ Machine::earliest_node() const
SharedPtr<Node> earliest;
for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) {
- const SharedPtr<Node> node = _active_nodes[i];
+ SharedPtr<Node> node = _active_nodes.at(i);
if (node) {
assert(node->is_active());
@@ -175,7 +213,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(const SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
+Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
{
assert(!node->is_active());
@@ -183,10 +221,10 @@ Machine::enter_node(const SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node>
* while all actions are still MIDI notes... */
size_t index = (rand() % MAX_ACTIVE_NODES);
for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) {
- if (_active_nodes[index] == NULL) {
+ if (_active_nodes.at(index)== NULL) {
node->enter(sink, _time);
assert(node->is_active());
- _active_nodes[index] = node;
+ _active_nodes.at(index) = node;
return true;
}
index = (index + 1) % MAX_ACTIVE_NODES;
@@ -201,16 +239,14 @@ Machine::enter_node(const SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node>
/** Exit an active node at the current _time.
*/
void
-Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
+Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
{
node->exit(sink, _time);
assert(!node->is_active());
- for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) {
- if (_active_nodes[i] == node) {
- _active_nodes[i].reset();
- }
- }
+ for (size_t i=0; i < MAX_ACTIVE_NODES; ++i)
+ if (_active_nodes.at(i) == node)
+ _active_nodes.at(i).reset();
// Activate successors to this node
// (that aren't aready active right now)
@@ -237,13 +273,13 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
} else {
- for (Node::Edges::const_iterator s = node->edges().begin();
- s != node->edges().end(); ++s) {
+ for (Node::Edges::const_iterator e = node->edges().begin();
+ e != node->edges().end(); ++e) {
const double rand_normal = rand() / (double)RAND_MAX; // [0, 1]
- if (rand_normal <= (*s)->probability()) {
- SharedPtr<Node> head = (*s)->head();
+ if (rand_normal <= (*e)->probability()) {
+ SharedPtr<Node> head = (*e)->head();
if ( ! head->is_active())
enter_node(sink, head);
@@ -269,7 +305,7 @@ Machine::run(const Raul::TimeSlice& time)
if (_is_finished)
return 0;
- const SharedPtr<Raul::MIDISink> sink = _sink.lock();
+ SharedPtr<Raul::MIDISink> sink = _sink.lock();
const TickTime cycle_end_ticks = time.start_ticks() + time.length_ticks() - 1;
const BeatCount cycle_end_beats = time.ticks_to_beats(cycle_end_ticks);
@@ -330,7 +366,7 @@ Machine::run(const Raul::TimeSlice& time)
}
- assert(this_time <= time.length_beats());
+ //assert(this_time <= time.length_beats());
return this_time;
}