-
Notifications
You must be signed in to change notification settings - Fork 4
/
loadManager.js
230 lines (187 loc) · 6.53 KB
/
loadManager.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
// possible resources: world, bike, explode
var resources = {
_ready: false // this is the only property that is not a resource. means that the essential resources are loaded
};
var workProgress = {
items: {}, // items that are currently in processing (models)
ondone: null, // called after all items are done
onprogress: null // bool(float) called for progress report. receives [0-1] progress.
// should return true if next action should be async.
};
function updateProgress(name, status) {
if (status === null) {
delete workProgress.items[name];
if (workProgress.ondone && Object.keys(workProgress.items).length === 0) {
workProgress.onprogress = null;
workProgress.ondone();
workProgress.ondone = null;
}
return;
}
workProgress.items[name] = status;
}
function waitAsyncProgress(ondone) {
if (Object.keys(workProgress.items).length === 0) {
ondone();
return;
}
c2d.loadingScreen(0);
workProgress.ondone = ondone;
var curPercent = -1;
workProgress.onprogress = function(cp) {
//if (cp >= curPercent + 0.05) {
c2d.loadingScreen(cp);
// curPercent = cp;
//}
return false; // from here on, work will be sync (blocked) because we are in the loading screen.
};
}
// do the actual processing of the mesh after it is loaded.
// if async is true, this only start the process
function processWorldModel(loadedName, async) {
updateProgress(loadedName, "processing");
var rec = resources[loadedName];
var model = {};
var _start = new Date().getTime();
writeDebug("start " + loadedName);
createMeshData(rec.input, model);
createGridMeshBuffers(model, async,
function() { // done
rec.model = model;
writeDebug("done " + loadedName + " " + (new Date().getTime() - _start));
updateProgress(loadedName, null); // may call workProgress.ondone which may lead to startLife
},
function(pc) { // progress
if (workProgress.onprogress)
return workProgress.onprogress(pc)
return true; // working on the background, do async
}
);
}
function deleteModel(name) {
if (!resources[name] || !resources[name].model)
return;
writeDebug("deleting " + name);
delete resources[name].model;
}
function loadedWorld(loadedName, item, args) {
var model = { input: item, name: loadedName }; // onload- the hook that starts the level when it is loaded. see startLife()
resources[loadedName] = model; // clean up item
if (args.gridProc) {
processWorldModel(loadedName, args.async); // loading it now async
}
else {
updateProgress(loadedName, null); // not loading it now
}
}
//
function loadLevelWorld(lvl, gridProc, async) {
if (!levels[lvl])
return;
var name = levels[lvl].worldModel;
if (resources[name] === undefined || resources[name].input === undefined) { // not loaded and not processed
loadModel(worldModels[name].file, "none", name, loadedWorld, { gridProc:gridProc, async:async });
return;
}
if (resources[name].model === undefined && gridProc) { // loaded but not processed
processWorldModel(name, async);
}
}
function ensureLevelLoaded(lvlNum, howMany, ondone) {
var level = levels[lvlNum];
if (level === undefined)
throw new Error("level not found");
if (resources[level.worldModel] !== undefined && resources[level.worldModel].model !== undefined) {
if (ondone)
ondone();
return;
}
var async = true;
// delete everything. we don't want to take too much memory. keep the input though
for(var i = 0; i < lvlNum; ++i)
deleteModel(levels[i].worldModel);
for(var i = lvlNum + howMany; i < levels.length; ++i)
deleteModel(levels[i].worldModel);
// queue the loading, when the data arrive, do sync processing that is faster
for(var i = 0; i < howMany; ++i) {
loadLevelWorld(lvlNum + i, true, async);
}
if (ondone)
waitAsyncProgress(ondone);
}
function loadedResource(loadedName, item) {
resources[loadedName] = item;
updateProgress(loadedName, null);
// all resources needed to start game are ready.
if (resources.life && resources.bike)
{
resources._ready = true;
checkGLErrors("rcsinit");
}
}
// world meshes enter the loaded items registry as raw data
// other models enter the registry with their buffers
function loadModel(filename, method, name, onload, args) {
updateProgress(name, "loading");
var doneFunc = function(data) {
if (method === "indexed") {
var model = {};
createMeshBuffersIndexed(data, model);
onload(name, model, args);
}
else if (method === "inlined") {
var model = {};
createMeshBuffersInlined(data, model);
onload(name, model, args);
}
else if (method === "none") {
onload(name, data, args);
}
else
throw "unknown load method";
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
doneFunc( JSON.parse(xhttp.responseText));
}
else {
throw "failed loading file " + filename;
}
}
};
xhttp.open("GET", filename, true);
xhttp.send();
}
/*
var procworker = null;
function doWork(runObj, ondone, onprogress)
{
runObj.index = procworker.index;
procworker.waiting[procworker.index] = { ondone:ondone, onprogress:onprogress };
++procworker.index;
procworker.postMessage(runObj);
}
function startWorker()
{
procworker = new Worker("worker.js");
procworker.onmessage = function(e) {
var data = e.data;
if (data.progress) { // it's a progress message
var waiter = procworker.waiting[data.index];
if (waiter.onprogress)
waiter.onprogress(data.progress);
return;
}
writeDebug('Worker output');
var waiter = procworker.waiting[data.index];
delete procworker.waiting[data.index];
if (waiter.ondone)
waiter.ondone(data);
};
procworker.waiting = [];
procworker.index = 1;
// procworker.postMessage(); // start the worker
}
*/