/* This file is part of Machina. Copyright 2007-2013 David Robillard Machina 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 any later version. Machina 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 Machina. If not, see . */ #ifndef MACHINA_NODE_HPP #define MACHINA_NODE_HPP #include #include "machina/types.hpp" #include "Action.hpp" #include "MIDISink.hpp" #include "Schrodinbit.hpp" #include "Stateful.hpp" namespace machina { class Edge; using Raul::TimeDuration; using Raul::TimeStamp; using Raul::TimeUnit; /** A node is a state (as in a FSM diagram), or "note". * * It contains a action, as well as a duration and pointers to its * successors (states/nodes that (may) follow it). * * Initial nodes do not have enter actions (since they are entered at * an undefined point in time <= 0). */ class Node : public Stateful { public: Node(TimeDuration duration, bool initial=false); Node(const Node& copy); bool operator==(const Node& rhs) const; void set_enter_action(SPtr action); void set_exit_action(SPtr action); SPtr enter_action() const { return _enter_action; } SPtr enter_action() { return _enter_action; } SPtr exit_action() const { return _exit_action; } SPtr exit_action() { return _exit_action; } void enter(MIDISink* sink, TimeStamp time); void exit(MIDISink* sink, TimeStamp time); void edges_changed(); void add_edge(SPtr edge); void remove_edge(SPtr edge); SPtr remove_edge_to(SPtr node); bool connected_to(SPtr node); void set(URIInt key, const Raul::Atom& value); void write_state(Sord::Model& model); bool is_initial() const { return _is_initial; } bool is_active() const { return _is_active; } TimeStamp enter_time() const { return _enter_time; } TimeStamp exit_time() const { return _enter_time + _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); inline bool changed() { return _changed; } inline void set_changed() { _changed = true; } struct EdgeHeadOrder { inline bool operator()(const SPtr& a, const SPtr& b) { return a.get() < b.get(); } }; SPtr edge_to(SPtr head) const; typedef std::set, EdgeHeadOrder> Edges; Edges& edges() { return _edges; } SPtr random_edge(); private: Node& operator=(const Node& other); // undefined TimeStamp _enter_time; ///< valid iff _is_active TimeDuration _duration; SPtr _enter_action; SPtr _exit_action; Edges _edges; Schrodinbit _changed; bool _is_initial; bool _is_selector; bool _is_active; }; } // namespace machina #endif // MACHINA_NODE_HPP