-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.js
273 lines (230 loc) · 10.2 KB
/
app.js
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
define([
"jquery",
"underscore",
"backbone",
'dataFlow/dataFlow_loader',
"dataFlow/UI/workspaceView",
"dataFlow/UI/componentView",
"dataFlow/project",
"dataFlow/components/engine",
"dataFlow/pulse",
"dataFlow/freezeCalculations",
"text!src/css/orchestra.css"
],
function(
$,
_,
Backbone,
dataFlow,
WS,
ComponentView,
OrchestraProject,
PythonEngine,
Pulse,
Freezer,
OrchestraStyles
){
// Include general styles
//$("head").append("<link rel='stylesheet' href='"+require.toUrl("src/css/orchestra.css")+"' type='text/css' media='screen'>");
$("head").append("<style type='text/css'>"+OrchestraStyles+"</style");
var prevTimeStamp = 0, events = [];
window.LOG_TIME_EVENT = function(eventName, end){
var timestamp = (new Date()).getTime();
var timeobj = {};
timeobj[eventName] = timestamp - prevTimeStamp;
events.push(timeobj);
prevTimeStamp = timestamp;
if (end) {
//console.log(JSON.stringify(events).toString().replace(/},{/g,"\n"));
prevTimeStamp = 0;
events = [];
}
};
function App(Jupyter){
if (Jupyter) this.setupEngine(Jupyter);
else {console.error("Python Engine Not Initialized. All Python Functions will Error.");}
_.extend(this,Backbone.Events);
this.init();
}
App.prototype.init = function(){
this.currentProject = null;
_.bindAll(this,
"newProject",
// "loadParseProject",
"clearWorkspace",
"loadJSON",
"initializePulses"
);
this.workspace = new WS.Workspace();
this.workspace.createWorkspace();
// For initial, non-persisted testing
this.currentProject = new OrchestraProject();
// New components can be created directly in the workspace, as well as from the global nav:
var that = this;
this.workspace.on('createNewComponent',function(component){
that.newComponent.call(that,component);
});
};
App.prototype.newComponent = function(component){
var that=this,
position = component.position || this.workspace.getCurrentVisibleCenterPoint(),
cptObject = dataFlow.createComponentByName(component["functionName"],{
position: position
});
this.currentProject.addComponentToProject(cptObject);
// Handle "bake" equivalents: export STL, SVG, OBJ, Rendered Image, etc
cptObject.on('requestFileExport',function(o){that.exporter.export(o);});
new ComponentView(cptObject);
};
App.prototype.newProject = function(){
this.clearWorkspace();
this.loadWorkspace(this.currentProject);
};
App.prototype.clearWorkspace = function(){
Freezer.setFrozen(true);
console.warn('DO SOME TESTS TO MAKE SURE THAT ZOMBIES DONT REMAIN');
// Stop listening to the project to remove ref's to the project
this.stopListening();
// We'll remove the views directly here, since we don't actually want to remmove the components from the project
// model itself. That could cause weird behavior if a save occurred at the wrong moment, this is safer.
if (!_.isNull(this.currentProject)) {
_.each(this.currentProject.get('components').slice(0),function(cpt){
cpt.componentView.remove();
});
}
this.currentProject = new OrchestraProject();
// require(["dataFlow/projectLoader"],function(Loader){
// Loader.clearCurrentProject();
// });
this.workspace.render(); // render workspace once to remove wires from view
};
// App.prototype.save = function(){
// var proj = this.currentProject,
// that=this;
// if (_.isNull(proj)) throw new Error("No current project available to save");
//
// require(["dataFlow/projectLoader"],function(Loader){
// Loader.saveProjectToParse(proj,that.getDisplayState());
// });
// };
App.prototype.getDisplayState = function(){
return {
workspace: this.workspace.toJSON()
}
};
// App.prototype.loadParseProject = function(projectId){
// this.clearWorkspace();
// var that = this;
// require(["dataFlow/projectLoader"],function(Loader){
// // no reference necessary. The slider will clean itself up.
// Loader.loadProjectFromParse(projectId)
// .then(function(proj){
// console.log('\n\nLOADED PROJECT FROM PARSE');
// console.warn("VIEWER USED TO BE INITIALIZED HERE");
// that.loadWorkspace(proj);
// })
// .fail(function(e){
// if (e && e.code === 100) {
// // Server is unavailable. This is a fatal error, but for right now let's just enter demo mode
// alert("Server Unavailable. Entering Demo Mode.");
// that.setupDemoMode();
// } else {
// alert("Unknown fatal error. See console for more info.");
// console.log("Error details while trying to load project from Parse Server:");
// console.log(e);
// }
// });
// });
// };
// App.prototype.loadJSONProjectUrl = function(url){
// this.clearWorkspace();
// var that = this;
//
// require(["dataFlow/projectLoader"],function(Loader){
// Loader.loadProjectFromUrl(url,function(proj){
// console.log('\n\nLOADED PROJECT FROM FILE');
// that.loadWorkspace(proj);
// });
// });
// };
App.prototype.loadJSON = function(jsonData) {
this.clearWorkspace();
var that = this;
require(["dataFlow/project"],function(Project){
that.loadWorkspace(new Project(jsonData));
});
}
App.prototype.loadWorkspace = function(proj){
// Make sure no pulses occur while we're loading components and connections
Freezer.setFrozen(true);
var that = this;
this.currentProject = proj;
// Bubble up changes to the active project so we can trigger a 'project changed' event externally
this.listenTo(this.currentProject,'change',function(p){
that.trigger('change',p.toJSON());
});
// Draw Componets, Inputs and Outputs in workspace:
_.each(proj.get('components'),function(cpt){
// Attach file export capabilities
cpt.on('requestFileExport',function(o){that.exporter.export(o);});
new ComponentView(cpt);
});
// CONNECTIONS between I/O's can't be drawn until all components have been drawn
// (the views must exist before they can be connected)
// TODO: ELIMINATE THIS DEFER STATEMENT -- PERHAPS WITH A PROMISE? PERHAPS BY SETTING THE IOVIEW PROPERTY SYNCHRONOUSLY
// TODO: THEN PUTTING THE _.DEFER STATEMENT INSIDE THE DRAWALLCONNECTIONS FUNCTION?
_.defer(function(){
_.each(proj.get('components'),function(cpt){
_.each(cpt.inputs,function(ipt){
var inputView = ipt.IOView;
if (inputView) {
inputView.drawAllConnections();
}
});
});
});
if (proj.get('contextData')) {
this.workspace.fromJSON(proj.get('contextData')["workspace"]);
}
this.initializePulses(proj);
};
App.prototype.initializePulses = function(proj){
// Unfreeze so we can follow pulses
Freezer.setFrozen(false);
// Trigger "change" events on components with inputs without connections, one per component
// These are the beginnings of the "graph"
_.each(proj.get('components'),function(cpt){
var disconnectedCount = 0;
_.each(cpt.inputs,function(ipt){
if ( _.keys(ipt._listeningTo).length === 0 && !ipt.getTree().isEmpty()) {
disconnectedCount++;
} else if (ipt.get('invisible') === true) {
disconnectedCount++;
}
});
// if all inputs to a component are disconnected, trigger a pulse
// to make sure the component recalculates now that all connections are in place
if (disconnectedCount === cpt.inputs.length) {
//console.log('master trigger now');
var start = cpt.inputs[0];
start.trigger('pulse',new Pulse({startPoint:start}));
}
});
};
App.prototype.setupEngine = function (J) {
console.warn("SETUP ENGINE NEEDS TO BE IMPLEMENTED NOW")
PythonEngine.setup(J);
PythonEngine.resetTranscript();
};
App.prototype.getTranscript = function () {
return PythonEngine.getTranscript();
};
App.prototype.close = function () {
console.warn("Orchestra.Close() not yet implemented. It needs to clean up and remove UI.");
this.workspace.destroy();
this.trigger('closed',this.currentProject.toJSON());
this.off();
};
return App;
}
);