#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" 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("waves",new Waves(),category["source"]); add_type("still_image",new Still_image(),category["source"]); add_type("video_loader",new Video_loader(),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"]); 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("vhs",new VHS(),category["fx"]); add_type("echo_trails",new Echo_trails(),category["fx"]); add_type("video_feedback",new Video_feedback(),category["fx"]); } bool Signal_input::connect(Node* source) { connection=dynamic_cast(source); if (connection) return true; else return false; } float Signal_input::get(const Time_spec& time){ //gets input and updates variable if (connection){ return (((Signal_node*)connection)->get_output(time)); } else return 0.0f; } 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){ return (((Image_node*)connection)->get_image_output(time)); } else return nullptr; } float 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"); }; void Node_factory::list_node(Rotor::Node* type,xmlIO XML,int i=0){ 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","UID",type->UID,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); 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); XML.addAttribute("attribute","value",attribute.second->value,j); if (attribute.second->vals.size()){ //document attribute enumeration 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","string",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){ 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["UID"]=_node->UID; 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; 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; attribute["value"]=attr.second->value; if (attr.second->vals.size()){ //document attribute enumeration attribute["type"]="enum"; attribute["options"]=Json::arrayValue; for (auto val: attr.second->vals){ attribute["options"].append(val); } } else attribute["type"]="string"; node["attributes"].append(attribute); } } category["nodes"].append(node); } JSON["category"].append(category); } } void Node_factory::list_nodes(Json::Value &JSON){ JSON["nodeslist"]=Json::arrayValue; for (auto& type: type_map) { if (type.second->description!="") { //blank description = internal/ testing node Json::Value node; node["type"]=type.first; node["title"]=type.second->title; node["inputs"]=type.second->duplicate_inputs?"expandable":"fixed"; if (dynamic_cast (type.second)!=nullptr) node["output"]="signal"; if (dynamic_cast (type.second)!=nullptr) node["output"]="image"; node["description"]=type.second->description; node["UID"]=type.second->UID; if (type.second->inputs.size()){ node["signal_inputs"]=Json::arrayValue; for (auto& input: type.second->inputs) { Json::Value signal_input; signal_input["title"]=input->title; signal_input["description"]=input->description; node["signal_inputs"].append(signal_input); } } if (dynamic_cast (type.second)!=nullptr) { if ((dynamic_cast(type.second))->image_inputs.size()){ node["image_inputs"]=Json::arrayValue; for (auto& input: (dynamic_cast(type.second))->image_inputs) { Json::Value image_input; image_input["title"]=input->title; image_input["description"]=input->description; node["image_inputs"].append(image_input); } } } if (type.second->parameters.size()){ node["parameters"]=Json::arrayValue; for (auto& param: type.second->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; node["parameters"].append(parameter); } } if (type.second->attributes.size()){ node["attributes"]=Json::arrayValue; for (auto& attr: type.second->attributes) { Json::Value attribute; attribute["name"]=attr.first; attribute["title"]=attr.second->title; attribute["description"]=attr.second->description; attribute["value"]=attr.second->value; if (attr.second->vals.size()){ //document attribute enumeration attribute["type"]="enum"; attribute["options"]=Json::arrayValue; for (auto val: attr.second->vals){ attribute["options"].append(val); } } else attribute["type"]="string"; node["attributes"].append(attribute); } } JSON["nodeslist"].append(node); } } }