#include "rotor.h" #include "nodes_signals.h" #include "nodes_channels.h" #include "nodes_source.h" #include "nodes_audio_analysis.h" #include "nodes_maths.h" #include "nodes_drawing.h" #include "nodes_filters.h" #include "nodes_transform.h" #include "nodes_UI.h" using namespace Rotor; using Poco::Logger; Node_factory::Node_factory(){ //for now, statically load prototype map in constructor //how to deal with category //have an associative array of arrays of pointers to nodes, "category" //this can be hard coded also // category["Signals"]=vector(); add_type("time",new Time(),category["Signals"]); add_type("track_time",new Track_time(),category["Signals"]); add_type("at_track_time",new At_track_time(),category["Signals"]); // add_type("signal_output",new Signal_output()); add_type("testcard",new Testcard()); // category["Channels"]=vector(); add_type("invert",new Invert(),category["Channels"]); add_type("monochrome",new Monochrome(),category["Channels"]); add_type("blend",new Blend(),category["Channels"]); add_type("image_arithmetic",new Image_arithmetic(),category["Channels"]); add_type("alpha_merge",new Alpha_merge(),category["Channels"]); add_type("difference_matte",new Difference_matte(),category["Channels"]); add_type("rgb_levels",new RGB_levels(),category["Channels"]); add_type("luma_levels",new Luma_levels(),category["Channels"]); category["Source"]=vector(); add_type("signal_colour",new Signal_colour(),category["Source"]); add_type("signal_greyscale",new Signal_greyscale(),category["Source"]); add_type("shape",new Shape(),category["Source"]); add_type("text",new Text(),category["Source"]); add_type("lyrics",new Lyrics(),category["Source"]); add_type("waves",new Waves(),category["Source"]); add_type("still_image",new Still_image(),category["Source"]); add_type("video_loader",new Video_loader(),category["Source"]); add_type("video_bank",new Video_bank(),category["Source"]); add_type("svg",new Svg(),category["Source"]); category["Distort"]=vector(); add_type("mirror",new Mirror(),category["Distort"]); add_type("transform",new Transform(),category["Distort"]); category["Editing"]=vector(); add_type("video_cycler",new Video_cycler(),category["Editing"]); add_type("video_output",new Video_output(),category["Editing"]); add_type("act_segmenter",new Act_segmenter(),category["Editing"]); category["Audio"]=vector(); add_type("audio_analysis",new Audio_analysis(),category["Audio"]); add_type("audio_analysis2",new Audio_analysis2(),category["Audio"]); add_type("intensity_segmenter",new Intensity_segmenter(),category["Audio"]); category["Maths"]=vector(); add_type("comparison",new Comparison(),category["Maths"]); //TODO: alias to symbols add_type("arithmetic",new Arithmetic(),category["Maths"]); //TODO: alias to symbols add_type("bang",new Is_new_integer(),category["Maths"]); add_type("on_off",new On_off(),category["Maths"]); add_type("random",new Random(),category["Maths"]); add_type("noise",new Noise(),category["Maths"]); category["FX"]=vector(); add_type("blur",new Blur(),category["FX"]); add_type("mosaic",new Mosaic(),category["FX"]); //add_type("vhs",new VHS(),category["FX"]); add_type("echo_trails",new Echo_trails(),category["FX"]); add_type("video_feedback",new Video_feedback(),category["FX"]); category["UI"]=vector(); add_type("ui_text",new UI_text(),category["UI"]); add_type("number",new Number(),category["UI"]); add_type("dial",new Dial(),category["UI"]); add_type("slider",new Slider(),category["UI"]); } bool Signal_input::connect(Node* source) { connection=dynamic_cast(source); if (connection) return true; else return false; } double Signal_input::get(const Time_spec& time){ //gets input and updates variable if (connection){ return (((Signal_node*)connection)->get_output(time)); } else return 0.0; } bool Image_input::connect(Node* source) { connection=dynamic_cast(source); if (connection) return true; else return false; } Image* Image_input::get(const Frame_spec& time){ //gets input and updates variable if (connection){ struct timeval begin_time; gettimeofday(&begin_time, NULL); Image* im=(((Image_node*)connection)->get_image_output(time)); struct timeval end_time; gettimeofday(&end_time, NULL); time_taken=((end_time.tv_sec-begin_time.tv_sec) + ((end_time.tv_usec-begin_time.tv_usec)/1000000.0)); return im; } else return nullptr; } double Parameter::get(const Time_spec& time){ //gets input and updates variable if (connection){ value = ((Signal_node*)connection)->get_output(time); } return value; } bool Node_factory::list_node(const string &t,xmlIO XML){ for (auto& type: type_map) { if (type.first==t) { list_node(type.second,XML); return true; } } XML.addValue("error","Node /"+t+"/ not found"); return false; }; bool Node_factory::list_node(const string &t,Json::Value &JSON){ for (auto& type: type_map) { if (type.first==t) { JSON["node"]=list_node(type.second); return true; } } JSON["error"]="Node /"+t+"/ not found"; return false; }; Json::Value Node_factory::list_node(Rotor::Node* _node){ Json::Value node; node["type"]=_node->type; node["title"]=_node->title; node["inputs"]=_node->duplicate_inputs?"expandable":"fixed"; if (dynamic_cast (_node)!=nullptr) node["output"]="signal"; if (dynamic_cast (_node)!=nullptr) node["output"]="image"; node["description"]=_node->description; node["NODEID"]=_node->NODEID; node["UItype"]=_node->UItype; if (_node->inputs.size()){ node["signal_inputs"]=Json::arrayValue; for (auto& input: _node->inputs) { Json::Value signal_input; signal_input["title"]=input->title; signal_input["description"]=input->description; node["signal_inputs"].append(signal_input); } } if (dynamic_cast (_node)!=nullptr) { if ((dynamic_cast(_node))->image_inputs.size()){ node["image_inputs"]=Json::arrayValue; for (auto& input: (dynamic_cast(_node))->image_inputs) { Json::Value image_input; image_input["title"]=input->title; image_input["description"]=input->description; node["image_inputs"].append(image_input); } } } if (_node->parameters.size()){ node["parameters"]=Json::arrayValue; for (auto& param: _node->parameters) { Json::Value parameter; parameter["name"]=param.first; parameter["type"]=param.second->type; parameter["title"]=param.second->title; parameter["description"]=param.second->description; parameter["value"]=param.second->value; parameter["min"]=param.second->min; parameter["max"]=param.second->max; parameter["step"]=param.second->step; node["parameters"].append(parameter); } } if (_node->attributes.size()){ node["attributes"]=Json::arrayValue; for (auto& attr: _node->attributes) { Json::Value attribute; attribute["name"]=attr.first; attribute["title"]=attr.second->title; attribute["description"]=attr.second->description; if (attr.second->vals.size()){ //document attribute enumeration attribute["value"]=attr.second->value; attribute["type"]="enum"; attribute["options"]=Json::arrayValue; for (auto val: attr.second->vals){ attribute["options"].append(val); } } else { attribute["type"]=attr.second->type; if (attr.second->type=="array"){ attribute["value"]=Json::arrayValue; } else attribute["value"]=attr.second->value; } node["attributes"].append(attribute); } } return node; } void Node_factory::list_node(Rotor::Node* type,xmlIO XML,int i){ XML.addTag("node"); XML.addAttribute("node","type",type->type,i); XML.addAttribute("node","inputs",type->duplicate_inputs?"expandable":"fixed",i); XML.addAttribute("node","title",type->title,i); XML.addAttribute("node","description",type->description,i); XML.addAttribute("node","NODEID",type->NODEID,i); XML.addAttribute("node","UItype",type->UItype,i); if (dynamic_cast (type)!=nullptr) XML.addAttribute("node","output","signal",i); if (dynamic_cast (type)!=nullptr) XML.addAttribute("node","output","image",i); XML.pushTag("node",i); //if (type->description!="") { // XML.addTag("description"); // XML.setValue("description",type->description,0); //} int j=0; for (auto& input: type->inputs) { XML.addTag("signal_input"); XML.addAttribute("signal_input","title",input->title,j); XML.addAttribute("signal_input","description",input->description,j); j++; } j=0; if (dynamic_cast (type)!=nullptr) { for (auto& input: (dynamic_cast(type))->image_inputs) { XML.addTag("image_input"); XML.addAttribute("image_input","title",input->title,j); XML.addAttribute("image_input","description",input->description,j); j++; } } j=0; for (auto& parameter: type->parameters) { XML.addTag("parameter"); XML.addAttribute("parameter","name",parameter.first,j); XML.addAttribute("parameter","type",parameter.second->type,j); XML.addAttribute("parameter","title",parameter.second->title,j); XML.addAttribute("parameter","description",parameter.second->description,j); XML.addAttribute("parameter","value",parameter.second->value,j); XML.addAttribute("parameter","min",parameter.second->min,j); XML.addAttribute("parameter","max",parameter.second->max,j); XML.addAttribute("parameter","step",parameter.second->step,j); j++; } j=0; for (auto& attribute: type->attributes) { XML.addTag("attribute"); XML.addAttribute("attribute","name",attribute.first,j); XML.addAttribute("attribute","title",attribute.second->title,j); XML.addAttribute("attribute","description",attribute.second->description,j); if (attribute.second->vals.size()){ //document attribute enumeration XML.addAttribute("attribute","value",attribute.second->value,j); XML.addAttribute("attribute","type","enum",j); XML.pushTag("attribute",j); int k=0; for (auto val: attribute.second->vals){ XML.addTag("option"); XML.addAttribute("option","value",val,k); k++; } XML.popTag(); } else { XML.addAttribute("attribute","type",attribute.second->type,j); if (attribute.second->type=="array"){ XML.pushTag("attribute",j); XML.addTag("value"); XML.popTag(); } else XML.addAttribute("attribute","value",attribute.second->value,j); } j++; } XML.popTag(); } void Node_factory::list_nodes(xmlIO XML){ int i=0; for (auto& type: type_map) { if (type.second->description!="") { //blank description = internal/ testing node list_node(type.second,XML,i); i++; } } } void Node_factory::list_categories(xmlIO XML){ int i=0; for (auto& _category: category) { XML.addTag("category"); XML.addAttribute("category","name",_category.first,i); XML.pushTag("category",i); int j=0; for (auto& node: _category.second){ list_node(node,XML,j); j++; } XML.popTag(); i++; } } void Node_factory::list_categories(Json::Value &JSON){ JSON["category"]=Json::arrayValue; for (auto& _category: category) { Json::Value category; category["name"]=_category.first; category["nodes"]=Json::arrayValue; for (auto& _node: _category.second){ //cerr<<"Adding "<<_category.first<<":"<<_node->type<description!="") { //blank description = internal/ testing node JSON["nodeslist"].append(list_node(type.second)); } } }