#ifndef ROTOR_H #define ROTOR_H #include #include #include #include #include #include #include namespace Rotor { class Node; template class Node_type; class Audio_frame{ public: Audio_frame(uint16_t *_samples,int _channels,int _numsamples){ samples=_samples; channels=_channels; numsamples=_numsamples; } uint16_t *samples; int channels,numsamples; }; class Frame_parameters{ public: Frame_parameters(double _time,double _framerate,double _duration,int _w,int _h,Audio_frame *_audio=nullptr) { time=_time; framerate=_framerate; duration=_duration; w=_w; h=_h;audio=_audio;}; Frame_parameters(int _frame,double _framerate,double _duration,int _w,int _h,Audio_frame *_audio=nullptr) { time=((double)_frame)/_framerate; framerate=_framerate; duration=_duration; w=_w; h=_h;audio=_audio;}; int h,w; Frame_parameters lastframe() const{ return Frame_parameters(time-(1.0/framerate),framerate,duration,w,h); } Frame_parameters nextframe() const{ return Frame_parameters(time+(1.0/framerate),framerate,duration,w,h); } double time; //num/denom ? double framerate; double duration; Audio_frame *audio; }; class Variable { //pure virtual base type for variable pointers public: Variable(){connection=nullptr;}; virtual void init(std::string s)=0; virtual ~Variable(){}; virtual bool connect(Node* target)=0; virtual std::string get_type()=0; Node* connection; bool connectable; }; template class Variable_type : public Variable { public: Variable_type(bool _c){connectable=_c;}; void init(std::string s){ std::istringstream cur(s); cur >> value; } std::string get_type(){ //need this to output node templates return "unknown"; } bool connect(Node* target){ if (connectable){ if (dynamic_cast*>(target)){ connection=target; return true; } } return false; } const T& get(const Frame_parameters &frame){ if (connection){ return (dynamic_cast*>(connection))->get_output(frame); } return value; } T value; }; template class Variable_array: public Variable_type { public: Variable_array(){}; void add(int num=1){ for (int i=0;iwhich){ return values[which].connect(target); } return false; } const T& get(int which,const Frame_parameters &frame){ if (values.size()>which){ return values[which].get(frame); } return value; } std::vector> values; T value; }; //don't forget the dupliicate inlets //it needs to be a property of a var //vars need to be: //std::unordered_map>> //?? //or could it be that a var has properties //var needs to be a class? //or multi var could be a subclass of var? //with an extra accessor const T& get(int which,const Frame_parameters &frame) //in Node we could have create_multi_inlet() and add_multi_inlet() class Node { //base type for node pointers public: virtual ~Node(){ for (auto v:vars){ delete v.second; } } bool connect(std::string v,Node *t){ auto var=vars.find(v); if (var!=vars.end()){ if ((*var).second->connect(t)){ return true; } } return false; } virtual Node* clone(std::map &_settings)=0; std::string node_type; std::string node_id; std::string id; std::string description; std::string title; std::string ui_type; std::string output_type; std::unordered_map vars; }; template class Node_type : public Node { public: virtual const NT& get_output(const Frame_parameters &frame)=0; void init(std::map settings){ for (auto s:settings) { if (vars.find(s.first)!=vars.end()){ vars[s.first]->init(s.second); //printf("set %s to %s\n",s.first.c_str(),s.second.c_str()); } } } template Variable_type* create_inlet(std::string name){ vars[name]=new Variable_type(true); return (dynamic_cast*>(vars[name])); } template Variable_type* create_attribute(std::string name){ vars[name]=new Variable_type(false); return (dynamic_cast*>(vars[name])); } template Variable_array* create_array(std::string name){ vars[name]=new Variable_array(); return (dynamic_cast*>(vars[name])); } }; } #endif //ROTOR_H