From: Peep P. <so...@us...> - 2004-03-28 18:04:46
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30840 Modified Files: object.c object.h Log Message: Separated object loading and program compilation into load_object() and compile_prog() - allows for recompilation in situ Index: object.c =================================================================== RCS file: /cvsroot/agd/server/src/object.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- object.c 21 Mar 2004 10:34:47 -0000 1.11 +++ object.c 28 Mar 2004 17:53:27 -0000 1.12 @@ -9,33 +9,27 @@ player_t *this_player; object_t *this_ob, *previous_ob; -/* this for clone_object() */ -void *copy_fun(void *voidf) -{ - function_t *f = voidf, *p; - p = type_xmalloc(function_t); - *p = *f; - return p; -} - void free_fun(void *p) { int i; function_t *f = p; -#if 0 + for(i=0;i<f->args.length;i++) free_var(f->args.data[i]); if(f->args.data) xfree(f->args.data); + + /* Can't do this. Need string tables. */ +#if 0 for(i=0;i<f->code.length;i++) { - int vmt = (int) f->code.data[i]; - /* Inefficient and risky, yes. */ - if((vmt == F_VAR_T || vmt == F_LOCAL) && vmt > F_HIGHEST) { - free_var(f->code.data[i]); - } + if((int) f->code.data[i] == F_PUSH_STRING) { + i++; + if(f->code.data[i]) + xfree(f->code.data[i]); + } } - xfree(f->code.data); #endif + xfree(f->code.data); } void destruct(object_t *ob) @@ -47,7 +41,8 @@ ob->flags |= O_DESTRUCTED; - unref_ob(ob->parent, NULL); + /*unref_ob(ob->parent, NULL);*/ + if(ob->iaob) { net_disconnect(ob->iaob); ob->iaob->ob = NULL; @@ -66,18 +61,13 @@ void actual_destruct(object_t *ob) { list_remove(&all_objects, ob); - if(unref_prog(ob->prog)) { - ob->prog = NULL; - } - /* - free_array(&ob->prog->fun_table, NULL); - free_array(&ob->prog->functions, free_fun); - xfree(ob->prog); - */ + unref_prog(&ob->prog); + free_array(&ob->variables, (void (*)(void*))free_var); if(ob->name) xfree(ob->name); + xfree(ob); } @@ -102,50 +92,98 @@ prog->ref++; } -/* Returns 1 if program was freed. */ -int unref_prog(program_t *prog) +void unref_prog(program_t **prog) { - if(!prog) - return 0; + program_t *p = *prog; + + if(!p) + return; - prog->ref--; - if(prog->ref <= 0) { - free_array(&prog->functions, free_fun); - free_array(&prog->fun_table, NULL); - xfree(prog); - return 1; + p->ref--; + if(p->ref <= 0) { + free_array(&p->functions, free_fun); + free_array(&p->fun_table, NULL); + xfree(p); + *prog = NULL; } - return 0; } object_t *find_object(char *s) { list_t *p; - char *name; - - if(s[strlen(s)-2] != '.') { - char *p = xmalloc(strlen(s) + 3); - strcpy(p, s); - strcat(p, ".c"); - name = p; - } else { - name = s; - } + if(!all_objects.data) + return NULL; + for(p = &all_objects; p; p = p->next) { object_t *ob = p->data; - if(ob->name && strcmp(name, ob->name) == 0) { - if(name != s) - xfree(name); + /* I'd rather not have the check for ob->name here. */ + if(ob->name && strcmp(s, ob->name) == 0) { return ob; } } - if(name != s) - xfree(name); return NULL; } +object_t *load_object(char *path) +{ + object_t *ob, + *saved_this_ob, + *saved_prev_ob; + + if(!legal_path(path)) { + printf("load_object(): illegal path name \"%s\"!\n", path); + return NULL; + } + + saved_this_ob = this_ob; + saved_prev_ob = previous_ob; + previous_ob = saved_this_ob; + + ob = find_object(path); + this_ob = ob; + if(ob) { + /* Try to recompile the object's + * code. */ + program_t *new_prog; + new_prog = compile_prog(path); + if(!new_prog) { + /* Runtime? */ + ob = NULL; + goto out; + } else { + unref_prog(&ob->prog); + /* new_prog is already referenced by compile_prog() */ + ob->prog = new_prog; + apply(ob, "create", NULL); + goto out; + } + } + + /* path = remove_extension(path); ? */ + ob = type_xmalloc(object_t); + memset(ob, 0, sizeof(object_t)); + ob->name = path; + + this_ob = ob; + + ob->prog = compile_prog(path); + if(!ob->prog) { + xfree(ob); + ob = NULL; + goto out; + } + + list_push(&all_objects, ob); + apply(ob, "create", NULL); + +out: + this_ob = saved_this_ob; + previous_ob = saved_prev_ob; + return ob; +} + object_t *clone_object(char *name) { object_t *base_ob, *new_ob; @@ -156,15 +194,17 @@ if(!base_ob) return NULL; } - + +#ifdef DEBUG debug("dfun", "cloning object %s\n", name); +#endif - ref_ob(base_ob, NULL); +/* ref_ob(base_ob, NULL);*/ new_ob = type_xmalloc(object_t); memset(new_ob, 0, sizeof(object_t)); new_ob->parent = base_ob; new_ob->name = xmalloc(strlen(base_ob->name) + 10); - sprintf(new_ob->name, "%s#%d", base_ob->name, base_ob->ref); + sprintf(new_ob->name, "%s#%d", base_ob->name, base_ob->prog->ref); new_ob->prog = base_ob->prog; ref_prog(new_ob->prog); @@ -178,16 +218,10 @@ return new_ob; } -/* This is pointless. */ -int interactivep(object_t *ob) -{ - return ob && ob->iaob; -} - void tell_object(object_t *ob, char *s) { player_t *p; - if(!interactivep(ob)) { + if(!ob || !ob->iaob) { return; } p = ob->iaob; @@ -195,7 +229,6 @@ } -#ifdef DEBUG void report_obs(void) { printf("this_ob: %p ", this_ob); @@ -236,4 +269,3 @@ } printf("-----------------------------------------\n"); } -#endif Index: object.h =================================================================== RCS file: /cvsroot/agd/server/src/object.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- object.h 18 Mar 2004 20:45:20 -0000 1.6 +++ object.h 28 Mar 2004 17:53:27 -0000 1.7 @@ -36,14 +36,10 @@ void ref_ob(object_t *ob, variable_t *v); void unref_ob(object_t *ob, variable_t *v); void ref_prog(program_t *prog); -int unref_prog(program_t *prog); +void unref_prog(program_t **prog); object_t *find_object(char *name); +object_t *load_object(char *path); object_t *clone_object(char *name); -int interactivep(object_t *ob); -/* -object_t *this_object(void); -object_t *previous_object(void); -*/ void tell_object(object_t *ob, char *s); void do_exec(object_t *ob); char *file_name(object_t *ob); |