1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "rotor.h"
using namespace Rotor;
const string Graph::toString(){
string xmlgraph;
if (loaded) {
xml.copyXmlToString(xmlgraph);
return xmlgraph;
}
else return "";
}
vector<Node*> Graph::find_nodes(const string &type){
vector<Node*> found;
for (std::unordered_map<string,Node*>::iterator it=nodes.begin();it!=nodes.end();++it) {
if (it->second->type==type) found.push_back(it->second);
}
return found;
};
Node* Graph::find_node(const string &type){
for (std::unordered_map<string,Node*>::iterator it=nodes.begin();it!=nodes.end();++it) {
if (it->second->type==type) return it->second;
}
return nullptr; //can be tested against
};
bool Graph::signal_render(string &signal_xml,const float framerate) {
if (find_node("signal_output")) {
Signal_output *signal_output=dynamic_cast<Signal_output*>(find_node("signal_output"));
return signal_output->render(duration,framerate,signal_xml);
}
cerr<<"Rotor: signal output node not found"<<endl;
return false;
}
bool Graph::video_render(const string &output_filename,const string &audio_filename,const float framerate,float& progress) {
if (find_node("video_output")) {
Video_output *video_output=dynamic_cast<Video_output*>(find_node("video_output"));
return video_output->render(duration,framerate,output_filename,audio_filename,progress);
}
cerr<<"Rotor: video output node not found"<<endl;
return false;
}
bool Graph::load(string &filename){
loaded=false;
printf("loading graph: %s\n",filename.c_str());
if(xml.loadFile(filename) ){
init(xml.getAttribute("patchbay","ID","",0),xml.getValue("patchbay","",0));
if(xml.pushTag("patchbay")) {
int n1=xml.getNumTags("node");
for (int i1=0;i1<n1;i1++){
map<string,string> settings;
vector<string> attrs;
xml.getAttributeNames("node",attrs,i1);
for (auto& attr: attrs) {
settings[attr]=xml.getAttribute("node",attr,"",i1);
//cerr << "Got attribute: " << attr << ":" << xml.getAttribute("node",attr,"",i1) << endl;
}
settings["description"]=xml.getValue("node","",i1);
Node* node=factory.create(settings);
if (node) {
string nodeID=xml.getAttribute("node","ID","",i1);
cerr << "Rotor: created node '"<<nodeID<<"': '"<< xml.getAttribute("node","type","",i1) << "'" << endl;
nodes[nodeID]=node;
if(xml.pushTag("node",i1)) {
int n2=xml.getNumTags("signal_input");
for (int i2=0;i2<n2;i2++){
nodes[nodeID]->create_signal_input(xml.getValue("signal_input","",i2));
string fromID=xml.getAttribute("signal_input","from","",i2);
if (nodes.find(fromID)!=nodes.end()) {
if (!nodes[nodeID]->inputs[i2]->connect((Signal_node*)nodes[fromID])){
cerr << "Rotor: graph loader cannot connect input " << i2 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
else cerr << "Rotor: linked input " << i2 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
else cerr << "Rotor: linking input " << i2 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
int n3=xml.getNumTags("image_input");
for (int i3=0;i3<n3;i3++){
((Image_node*)nodes[nodeID])->create_image_input(xml.getValue("image_input","",i3));
string fromID=xml.getAttribute("image_input","from","",i3);
if (nodes.find(fromID)!=nodes.end()) {
if (!(((Image_node*)nodes[nodeID])->image_inputs[i3]->connect((Image_node*)nodes[fromID]))){
cerr << "Rotor: graph loader cannot connect image input " << i3 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
else cerr << "Rotor: linked image input " << i3 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
else cerr << "Rotor: linking image input " << i3 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
int n4=xml.getNumTags("parameter_input");
for (int i4=0;i4<n4;i4++){
nodes[nodeID]->create_parameter_input(xml.getAttribute("parameter_input","parameter","",i4),xml.getValue("parameter_input","",i4));
string fromID=xml.getAttribute("parameter_input","from","",i4);
if (nodes.find(fromID)!=nodes.end()) {
if (!nodes[nodeID]->parameter_inputs[i4]->connect(nodes[fromID])){
cerr << "Rotor: graph loader cannot connect parameter input " << i4 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
return false;
}
else cerr << "Rotor: linked parameter input " << i4 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl;
}
else cerr << "Rotor: linking parameter input " << i4 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
nodes[nodeID]->link_params();
//extra key/value pairs that can be specific to sub-settings
int n5=xml.getNumTags("parameter");
for (int i5=0;i5<n5;i5++){
nodes[nodeID]->set_parameter(xml.getAttribute("parameter","name","",i5),xml.getAttribute("parameter","value","",i5));
}
if (n5>0) cerr << "Rotor: found " << n5 << " extra parameters for node '" << nodeID << "'" << endl;
xml.popTag();
}
}
else {
cerr << "Rotor: graph loader cannot find node '" << xml.getAttribute("node","type","",i1) << "'" << endl;
return false;
}
}
xml.popTag();
}
loaded=true;
return true;
}
else return false;
}
|