summaryrefslogtreecommitdiff
path: root/rotord/graph.cpp
blob: 655badb692af768f4e84ce78b0e7b2ec0a104cdb (plain)
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
#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);
	}
	else 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);
	}
	else 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;
}