comparison worker.c @ 0:76568becd6d6

Rhope Alpha 2a source import
author Mike Pavone <pavone@retrodev.com>
date Tue, 28 Apr 2009 23:06:07 +0000
parents
children 914ad38f9b59
comparison
equal deleted inserted replaced
-1:000000000000 0:76568becd6d6
1 #include "structs.h"
2 #include "interp.h"
3 #include "datum.h"
4 #include "parser.h"
5 #include "saveload.h"
6 #include <stdlib.h>
7 #include <string.h>
8
9 int vis_worker_from_string(datum ** inputlist, queue_entry * worker_entry)
10 {
11 int i;
12 worker_datum * work;
13 datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program);
14 work = output->c.generic.data;
15 find_worker(inputlist[0]->c.generic.data, NULL, NULL, worker_entry->instance->def->program, &work->def);
16 if(work->def)
17 add_program_ref(work->def->program);
18 for(i = 0; i < 32; ++i)
19 work->params[i] = NULL;
20 release_ref(inputlist[0]);
21 inputlist[0] = output;
22 return 0;
23 }
24
25 BOOL list_to_array(datum * list_dat, datum ** out_params, int num)
26 {
27 int i;
28 datum * params[2];
29 list_data * list = list_dat->c.generic.data;
30 if(num > list->num_entries) {
31 return FALSE;
32 }
33 for(i = 0; i < num; ++i)
34 out_params[i] = add_ref(list->entries[i]);
35 release_ref(list_dat);
36 return TRUE;
37 }
38
39 datum * array_to_list(datum ** in_params, int num, program * prog)
40 {
41 int i;
42 datum * params[2];
43 params[0] = create_list(prog);
44 for(i = 0; i < num; ++i)
45 {
46 params[1] = in_params[i];
47 vis_list_append(params, NULL);
48 }
49 return params[0];
50 }
51
52 int worker_populate_inputs(datum * inputWorker, datum * ioList, datum ** inputlist)
53 {
54 int i,j=0;
55 worker_datum * work = inputWorker->c.generic.data;
56 list_data * list = ioList->c.generic.data;
57 for(i = 0; i < work->def->num_inputs; ++i)
58 if(work->params[i])
59 {
60 DEBUGPRINTF("Setting input %d to %X from worker object\n", i, work->params[i]);
61 inputlist[i] = add_ref(work->params[i]);
62 }
63 else
64 {
65 if(j < list->num_entries)
66 {
67 DEBUGPRINTF("Setting input %d to %X from input %d\n", i, list->entries[j], j);
68 inputlist[i] = add_ref(list->entries[j]);
69 ++j;
70 }
71 else
72 {
73 ERRORPRINTF("Error: List passed to Do@Worker doesn't have enough entries for worker %s\n", work->def->name);
74 return -1;
75 }
76 }
77 return 0;
78 }
79
80 int vis_worker_do(datum ** inputlist, queue_entry * worker_entry)
81 {
82 //int i,j;
83 worker_datum * work;
84 //worker_def * def;
85 //list_data * list;
86 datum * inputWorker = inputlist[0];
87 datum * ioList = inputlist[1];
88 int returnval;
89 //release_ref(inputlist[0]);
90 work = inputlist[0]->c.generic.data;
91 //list_to_array(inputlist[1], inputlist, work->def->num_inputs);
92 /*list = inputlist[1]->c.generic.data;
93 j = 0;
94 DEBUGPRINTF("vis_worker_do: def_name: %s, num_inputs = %d, list length = %d\n", work->def->name, work->def->num_inputs, list->num_entries);
95 for(i = 0; i < work->def->num_inputs; ++i)
96 if(work->params[i])
97 {
98 DEBUGPRINTF("Setting input %d to %X from worker object\n", i, work->params[i]);
99 inputlist[i] = add_ref(work->params[i]);
100 }
101 else
102 {
103 DEBUGPRINTF("Setting input %d to %X from input %d, company name: %s\n", i, list->entries[j], j, list->entries[j]->company->name);
104 inputlist[i] = add_ref(list->entries[j]);
105 ++j;
106 }*/
107 returnval = worker_populate_inputs(inputWorker, ioList, inputlist);
108 release_ref(ioList);
109 if(returnval)
110 return returnval;
111 if(work->def->program != worker_entry->instance->def->program) {
112 prep_program(work->def->program );
113 }
114 returnval = execute_def(work->def, *worker_entry, inputlist, pack_list_sub_callback);
115 if(returnval == 0)
116 {
117 inputlist[0] = array_to_list(inputlist, work->def->num_outputs, worker_entry->instance->def->program);
118 /*vis_list_new(params, NULL);
119 DEBUGPRINTF("params[0] after vis_list_new: %X\n", params[0]);
120 for(i = 0; i < work->def->num_outputs; ++i)
121 {
122 params[1] = inputlist[i];
123 vis_list_append(params, NULL);
124 DEBUGPRINTF("params[0] after vis_list_append: %X\n", params[0]);
125 }
126 inputlist[0] = params[0];*/
127 }
128 release_ref(inputWorker);
129 return returnval;
130 }
131
132 int vis_worker_setinput(datum ** inputlist, queue_entry * worker_entry)
133 {
134 worker_datum * work;
135 inputlist[0] = copy_datum(inputlist[0], 0);
136 work = inputlist[0]->c.generic.data;
137 if(inputlist[1]->c.integers.num_a < 32)
138 work->params[inputlist[1]->c.integers.num_a] = inputlist[2];
139 else
140 {
141 puts("Error: Visuality currently only supports 32 inputs\n");
142 execute_active = FALSE;
143 return -1;
144 }
145 release_ref(inputlist[1]);
146 inputlist[1] = inputlist[2] = NULL;
147 return 0;
148 }
149
150 int vis_worker_add_worker_call(datum ** inputlist, queue_entry * worker_entry)
151 {
152 worker_datum * add_work;
153 worker_datum * work = inputlist[0]->c.generic.data;
154 int index;
155 add_work = inputlist[1]->c.generic.data;
156 /*index = add_work->def - work->def->program->deflist;
157 DEBUGPRINTF("work->def: %X, deflist: %X\n", work->def, worker_entry->instance->def->program->deflist);
158 DEBUGPRINTF("work->def->name: %X\n", work->def->name);*/
159 index = add_worker_to_def(work->def, add_work->def, 1.0, 1.0);
160 release_ref(inputlist[1]);
161 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
162 inputlist[1]->c.integers.num_a = index;
163 return 0;
164 }
165
166 int vis_worker_add_wire(datum ** inputlist, queue_entry * worker_entry)
167 {
168 worker_datum * work = inputlist[0]->c.generic.data;
169 add_wire(work->def, inputlist[1]->c.integers.num_a, inputlist[2]->c.integers.num_a, inputlist[3]->c.integers.num_a, inputlist[4]->c.integers.num_a);
170 release_ref(inputlist[1]);
171 release_ref(inputlist[2]);
172 release_ref(inputlist[3]);
173 release_ref(inputlist[4]);
174 return 0;
175 }
176
177 void list_change_program(list_data * list, program * new_prog)
178 {
179 int i;
180 for(i = 0; i < list->num_entries; ++i)
181 {
182 if(list->entries[i] && list->entries[i]->company->type_id < USER_DEFINED_TYPES)
183 {
184 list->entries[i] = copy_datum(list->entries[i], 0);
185 list->entries[i]->company = new_prog->companylist + list->entries[i]->company->type_id;
186 if(list->entries[i]->company->type_id == BUILTIN_TYPE_LIST)
187 list_change_program(list->entries[i]->c.generic.data, new_prog);
188 }
189 }
190 }
191
192 int vis_worker_add_constant(datum ** inputlist, queue_entry * worker_entry)
193 {
194 datum * constant = inputlist[1];
195 worker_datum * work = inputlist[0]->c.generic.data;
196 int index = add_constant(work->def, "code generated", 1.0, 1.0);
197 if(worker_entry->instance->def->program != work->def->program && constant->company->type_id < USER_DEFINED_TYPES)
198 {
199 constant = copy_datum(constant, 0);
200 constant->company = work->def->program->companylist + constant->company->type_id;
201 if(constant->company->type_id == BUILTIN_TYPE_LIST)
202 {
203 list_change_program(constant->c.generic.data, work->def->program);
204 }
205 }
206 work->def->implement_func->workerlist[index].value_index = constant;
207 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
208 inputlist[1]->c.integers.num_a = index;
209 return 0;
210 }
211
212 int vis_worker_add_input(datum ** inputlist, queue_entry * worker_entry)
213 {
214 worker_datum * work = inputlist[0]->c.generic.data;
215 int index = add_input_num(work->def, inputlist[1]->c.generic.data, inputlist[2]->c.integers.num_a, 1.0, 1.0);
216 release_ref(inputlist[1]);
217 release_ref(inputlist[2]);
218 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
219 inputlist[1]->c.integers.num_a = index;
220 return 0;
221 }
222
223 int vis_worker_add_output(datum ** inputlist, queue_entry * worker_entry)
224 {
225 worker_datum * work = inputlist[0]->c.generic.data;
226 int index = add_output_num(work->def, inputlist[1]->c.generic.data, inputlist[2]->c.integers.num_a, 1.0, 1.0);
227 release_ref(inputlist[1]);
228 release_ref(inputlist[2]);
229 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
230 inputlist[1]->c.integers.num_a = index;
231 return 0;
232 }
233
234 int vis_worker_add_objectget(datum ** inputlist, queue_entry * worker_entry)
235 {
236 worker_datum * work = inputlist[0]->c.generic.data;
237 int index = add_get_comp_room(work->def, inputlist[1]->c.generic.data, 1.0,1.0);
238 release_ref(inputlist[1]);
239 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
240 inputlist[1]->c.integers.num_a = index;
241 return 0;
242 }
243
244 int vis_worker_add_objectset(datum ** inputlist, queue_entry * worker_entry)
245 {
246 worker_datum * work = inputlist[0]->c.generic.data;
247 int index = add_set_comp_room(work->def, inputlist[1]->c.generic.data, 1.0,1.0);
248 release_ref(inputlist[1]);
249 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
250 inputlist[1]->c.integers.num_a = index;
251 return 0;
252 }
253
254 int vis_worker_add_globalget(datum ** inputlist, queue_entry * worker_entry)
255 {
256 worker_datum * work = inputlist[0]->c.generic.data;
257 int index;
258 char * name = malloc(inputlist[1]->c.generic.len + inputlist[2]->c.generic.len + 1);
259 memcpy(name, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len);
260 release_ref(inputlist[1]);
261 strcat(name, "::");
262 strcat(name, inputlist[2]->c.generic.data);
263 release_ref(inputlist[2]);
264 index = add_global_get(work->def, name, 1.0,1.0);
265 free(name);
266 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
267 inputlist[1]->c.integers.num_a = index;
268 return 0;
269 }
270
271 int vis_worker_add_globalset(datum ** inputlist, queue_entry * worker_entry)
272 {
273 worker_datum * work = inputlist[0]->c.generic.data;
274 int index;
275 char * name = malloc(inputlist[1]->c.generic.len + inputlist[2]->c.generic.len + 1);
276 memcpy(name, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len);
277 release_ref(inputlist[1]);
278 strcat(name, "::");
279 strcat(name, inputlist[2]->c.generic.data);
280 release_ref(inputlist[2]);
281 index = add_global_set(work->def, name, 1.0,1.0);
282 free(name);
283 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
284 inputlist[1]->c.integers.num_a = index;
285 return 0;
286 }
287
288 int vis_worker_new(datum ** inputlist, queue_entry * worker_entry)
289 {
290 int i;
291 datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program);
292 worker_datum * work = output->c.generic.data;
293 work->def = create_worker(worker_entry->instance->def->program, inputlist[0]->c.generic.data, 0, 0, USER_FLAG | WORKER_TYPE);
294 add_program_ref(work->def->program);
295 for(i = 0; i < 32; ++i)
296 work->params[i] = NULL;
297 release_ref(inputlist[0]);
298 inputlist[0] = output;
299 return 0;
300 }
301
302 int vis_worker_clear(datum ** inputlist, queue_entry * worker_entry)
303 {
304 int i;
305 worker_datum * work = inputlist[0]->c.generic.data;
306 VIS_EnterCriticalSection(work->def->implement_func->lock);
307 for(i = 0; i < work->def->implement_func->num_workers; ++i) {
308 if(work->def->implement_func->workerlist[i].type == CONSTANT) {
309 release_ref(work->def->implement_func->workerlist[i].value_index);
310 }
311 }
312 work->def->num_inputs = 0;
313 work->def->num_outputs = 0;
314 work->def->implement_func->num_workers = 0;
315 work->def->implement_func->num_wires = 0;
316 work->def->implement_func->dirty = TRUE;
317 VIS_LeaveCriticalSection(work->def->implement_func->lock);
318 return 0;
319 }
320
321 int vis_worker_uses(datum ** inputlist, queue_entry * worker_entry)
322 {
323 int i;
324 worker_datum * work = inputlist[0]->c.generic.data;
325 list_data * list = inputlist[1]->c.generic.data;
326 char ** new_uses;
327 if(list->num_entries)
328 {
329 new_uses = malloc(sizeof(char *) * list->num_entries);
330 for(i = 0; i < list->num_entries; ++i) {
331 if(list->entries[i]->company->type_id != BUILTIN_TYPE_STRING) {
332 ERRORPUTS("List passed to Uses@Worker contains non-string value(s)\n");
333 execute_active = FALSE;
334 return -1;
335 }
336 new_uses[i] = malloc(sizeof(char) * list->entries[i]->c.generic.len);
337 memcpy(new_uses[i], list->entries[i]->c.generic.data, list->entries[i]->c.generic.len);
338 }
339 } else
340 new_uses = NULL;
341 if(work->def->uses_stores)
342 free(work->def->uses_stores);
343 work->def->uses_stores = new_uses;
344 work->def->num_stores = list->num_entries;
345 release_ref(inputlist[1]);
346 return 0;
347 }
348
349 int vis_worker_setio_counts(datum ** inputlist, queue_entry * worker_entry)
350 {
351 int i;
352 int new_inputs = inputlist[1]->c.integers.num_a;
353 worker_datum * work = inputlist[0]->c.generic.data;
354 release_ref(inputlist[1]);
355 if(work->def->num_inputs < new_inputs)
356 {
357 work->def->input_types = realloc(work->def->input_types, sizeof(short)*new_inputs);
358 for(i = work->def->num_inputs; i < new_inputs; ++i)
359 work->def->input_types[i] = ANY_TYPE;
360 }
361 work->def->num_inputs = new_inputs;
362 work->def->num_outputs = inputlist[2]->c.integers.num_a;
363 release_ref(inputlist[2]);
364 return 0;
365 }
366
367 int vis_program_new(datum ** inputlist, queue_entry * worker_entry)
368 {
369 program * prog = new_program(START_DEF_STORAGE, START_COMP_STORAGE);
370 inputlist[0] = new_datum(BUILTIN_TYPE_PROGRAM, 2, 0, worker_entry->instance->def->program);
371 inputlist[0]->c.generic.data = prog;
372 inputlist[0]->c.generic.len = sizeof(program);
373 //inputlist[0]->union_type = 1;
374 return 0;
375 }
376
377 int vis_program_new_worker(datum ** inputlist, queue_entry * worker_entry)
378 {
379 int i;
380 datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program);
381 worker_datum * work = output->c.generic.data;
382 add_program_ref(inputlist[0]->c.generic.data);
383 work->def = create_worker(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data, 0, 0, USER_FLAG | WORKER_TYPE);
384 for(i = 0; i < 32; ++i)
385 work->params[i] = NULL;
386 release_ref(inputlist[1]);
387 inputlist[1] = output;
388 return 0;
389 }
390
391 int vis_program_add_worker(datum ** inputlist, queue_entry * worker_entry)
392 {
393 int i;
394 worker_datum * work = inputlist[1]->c.generic.data;
395 program * prog = inputlist[0]->c.generic.data;
396 datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program);
397 worker_datum * out_work = output->c.generic.data;
398 add_program_ref(inputlist[0]->c.generic.data);
399 out_work->def = create_worker(prog, work->def->name, work->def->num_inputs, work->def->num_outputs, WORKER_TYPE);
400 out_work->def->implement_func = work->def->implement_func;
401 out_work->def->type = work->def->type;
402 if(work->def->type & USER_FLAG)
403 out_work->def->program = work->def->program;
404 for(i = 0; i < work->def->num_inputs; ++i)
405 out_work->def->input_types[i] = out_work->def->input_types[i];
406 release_ref(inputlist[1]);
407 inputlist[1] = output;
408 return 0;
409 }
410
411 int vis_program_add_builtins(datum ** inputlist, queue_entry * worker_entry)
412 {
413 initpredefworkers((program *)inputlist[0]->c.generic.data);
414 return 0;
415 }
416
417 int vis_program_run(datum ** inputlist, queue_entry * worker_entry)
418 {
419 datum * params[32];
420 defchunk * current;
421 int i;
422 program * prog = inputlist[0]->c.generic.data;
423 params[0] = inputlist[1];
424 VIS_EnterCriticalSection(program_count_lock);
425 ++program_count;
426 VIS_LeaveCriticalSection(program_count_lock);
427 prep_program(prog);
428 add_program_ref(prog);
429 init_custom_worker(-1, NULL, prog->defs->deflist, main_callback, add_ref(inputlist[0]), params);
430 return 0;
431 }
432
433 int vis_program_find_worker(datum ** inputlist, queue_entry * worker_entry)
434 {
435 int i,returnval;
436 worker_datum * work;
437 worker_def * def;
438 program * prog = inputlist[0]->c.generic.data;
439 returnval = find_worker(inputlist[1]->c.generic.data, NULL, NULL, prog, &def);
440 release_ref(inputlist[0]);
441 if(returnval >= 0)
442 {
443 add_program_ref(prog);
444 release_ref(inputlist[1]);
445 inputlist[0] = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program);
446 inputlist[1] = NULL;
447 work = inputlist[0]->c.generic.data;
448 work->def = def;
449 for(i = 0; i < 32; ++i)
450 work->params[i] = NULL;
451 } else {
452 inputlist[0] = NULL;
453 }
454 return 0;
455 }
456
457 void free_worker(worker_def * def)
458 {
459 int i;
460 if(def->type & USER_FLAG && (def->type & TYPE_MASK) == WORKER_TYPE)
461 {
462 for(i = 0; i < def->implement_func->num_workers; ++i)
463 if(def->implement_func->workerlist[i].type == CONSTANT)
464 release_ref(def->implement_func->workerlist[i].value_index);
465 free(def->implement_func->workerlist);
466 free(def->implement_func->wirelist);
467 free(def->implement_func->workers_to_wires_up);
468 free(def->implement_func->workers_to_wires_down);
469 free(def->implement_func);
470 }
471 free(def->name);
472 free(def->input_types);
473 free(def->output_types);
474 }
475
476 void free_company(company * comp)
477 {
478 free(comp->methodlist);
479 free(comp->room_list);
480 }
481
482 void add_program_ref(program * prog)
483 {
484 VIS_EnterCriticalSection(prog->lock);
485 ++prog->refcount;
486 VIS_LeaveCriticalSection(prog->lock);
487 }
488
489 void release_program_ref(program * prog)
490 {
491 int i;
492 defchunk * current, *temp;
493 VIS_EnterCriticalSection(prog->lock);
494 --prog->refcount;
495 if(!prog->refcount) {
496 VIS_LeaveCriticalSection(prog->lock);
497 VIS_DeleteCriticalSection(prog->lock);
498 current = prog->defs;
499 while(current)
500 {
501 for(i = 0; i < current->num_defs; ++i)
502 {
503 free_worker(current->deflist + i);
504 }
505 current = current->next;
506 }
507 current = prog->defs;
508 while(current)
509 {
510 temp = current;
511 current = current->next;
512 free(temp);
513 }
514 //FIXME: We can't currently free the object definitions because of issues related to global stores
515 //for(i = 0; i < prog->num_companies; ++i)
516 // free_company(prog->companylist + i);
517 //free(prog->companylist);
518 free(prog);
519 } else {
520 VIS_LeaveCriticalSection(prog->lock);
521 }
522 }
523
524 /*
525 int vis_worker_begin_transaction(datum ** inputlist, queue_entry * worker_entry)
526 {
527 worker_def * def;
528 int returnval;
529 datum * params[2];
530 int i;
531 global_store * store;
532 list_data * list = inputist[0]->c.generic.data;
533 transaction * trans = malloc(sizeof(transaction) + list->num_entries - 1);
534 trans->num_stores = list->num_entries;
535 VIS_EnterCriticalSection(global_store_lock);
536 for(i = 0; i < list->num_entries; ++i)
537 {
538 params[0] = global_store_dict;
539 params[1] = add_ref(list->entries[i]);
540 vis_dict_index(params, NULL);
541 store = params[0]->c.generic.data;
542 while(store->inuse)
543 {
544 VIS_LeaveCriticalSection(global_store_lock);
545 #ifdef WIN32
546 Sleep(0);
547 #else
548 sleep(0);
549 #endif
550 VIS_EnterCriticalSection(global_store_lock);
551 }
552 store->inuse;
553 trans->stores[i] = params[0];
554 }
555 VIS_LeaveCriticalSection(global_store_lock;
556 release_ref(inputlist[0]);
557 def = deflist+inputlist[1]->c.integers.num_a;
558 release_ref(inputlist[1]);
559 list_to_array(inputlist[2], inputlist, def->num_inputs);
560 returnval = execute_def_data(def, *worker_entry, inputlist, trasnaction_sub_callback, transaction);
561 if(returnval == 0)
562 inputlist[0] = array_to_list(inputlist, def->num_outputs);
563 return returnval;
564 }
565
566 */
567