added scene parsing
parent
351c9ba713
commit
25c5f83fe4
|
@ -0,0 +1,160 @@
|
|||
#include "scene.h"
|
||||
|
||||
#include "ctype.h"
|
||||
#include "stdint.h"
|
||||
#include "stddef.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "hash.h"
|
||||
#include "malloc.h"
|
||||
#include "math.h"
|
||||
#include "world.h"
|
||||
|
||||
static
|
||||
struct type_handler_t {
|
||||
uintptr_t hash;
|
||||
char* type;
|
||||
type_handler_fn handler;
|
||||
} _type_handlers[99];
|
||||
|
||||
static
|
||||
int _type_handler_num = 0;
|
||||
|
||||
static
|
||||
struct type_handler_t* _find_handler_for(const char* type) {
|
||||
uintptr_t hash = hashstr(type);
|
||||
for(int i = 0; i < 99; ++i) {
|
||||
if(_type_handlers[i].hash == hash && strcmp(type, _type_handlers[i].type) == 0) {
|
||||
return _type_handlers + i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
struct type_handler_t* _new_handler_for(const char* type) {
|
||||
_type_handlers[_type_handler_num].type = malloc(strlen(type) * sizeof(char));
|
||||
strcpy(_type_handlers[_type_handler_num].type, type);
|
||||
_type_handlers[_type_handler_num].hash = hashstr(type);
|
||||
struct type_handler_t* ptr = _type_handlers + _type_handler_num;
|
||||
++_type_handler_num;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void set_type_handler(const char* type, type_handler_fn handler) {
|
||||
struct type_handler_t* ptr = _find_handler_for(type);
|
||||
if(ptr == NULL) {
|
||||
ptr = _new_handler_for(type);
|
||||
}
|
||||
ptr->handler = handler;
|
||||
}
|
||||
|
||||
static
|
||||
int fpeekc(FILE* file) {
|
||||
int c = fgetc(file);
|
||||
ungetc(c, file);
|
||||
return c;
|
||||
}
|
||||
|
||||
static
|
||||
int nextnw(FILE* file) {
|
||||
int next;
|
||||
char c;
|
||||
do {
|
||||
next = fgetc(file);
|
||||
c = (char)next;
|
||||
} while(isspace(c));
|
||||
return next;
|
||||
}
|
||||
|
||||
static
|
||||
void _parse_key(FILE* file, char* out) {
|
||||
char c;
|
||||
do {
|
||||
c = fgetc(file);
|
||||
if(c == ':') {
|
||||
*out = '\0';
|
||||
} else if(!isspace(c)) {
|
||||
*out = c;
|
||||
++out;
|
||||
}
|
||||
} while(c != ':');
|
||||
}
|
||||
|
||||
static
|
||||
void _parse_value(FILE* file, char* out, int* _argc, char** argv) {
|
||||
char c;
|
||||
int argc = 0;
|
||||
argv[argc] = out;
|
||||
++argc;
|
||||
do {
|
||||
c = fgetc(file);
|
||||
switch(c) {
|
||||
case ';':
|
||||
*out = '\0';
|
||||
break;
|
||||
case ',':
|
||||
*out = '\0';
|
||||
++out;
|
||||
argv[argc] = out;
|
||||
++argc;
|
||||
ungetc(nextnw(file), file);
|
||||
break;
|
||||
default:
|
||||
*out = c;
|
||||
++out;
|
||||
break;
|
||||
}
|
||||
} while(c != ';');
|
||||
*_argc = argc;
|
||||
}
|
||||
|
||||
static
|
||||
void _parse_config(FILE* file) {
|
||||
char key[24];
|
||||
char value[128];
|
||||
int argc = 0;
|
||||
char* argv[24];
|
||||
|
||||
char begin = nextnw(file);
|
||||
ungetc(begin, file);
|
||||
|
||||
_parse_key(file, key);
|
||||
ungetc(nextnw(file), file);
|
||||
_parse_value(file, value, &argc, argv);
|
||||
|
||||
struct type_handler_t* handler = _find_handler_for(key);
|
||||
|
||||
if(handler != NULL) {
|
||||
printf("found handler\n");
|
||||
if(begin == '!') {
|
||||
handler->handler(NULL, argc, argv);
|
||||
} else {
|
||||
handler->handler(make_object(), argc, argv);
|
||||
}
|
||||
}
|
||||
if(fpeekc(file) == EOF) return;
|
||||
}
|
||||
|
||||
static
|
||||
void _parse_scene(const char* filename) {
|
||||
FILE* file = fopen(filename, "r");
|
||||
int next;
|
||||
do {
|
||||
_parse_config(file);
|
||||
next = nextnw(file);
|
||||
ungetc(next, file);
|
||||
} while(next != EOF);
|
||||
}
|
||||
|
||||
void load_scene(const char* file) {
|
||||
world_clear();
|
||||
_parse_scene(file);
|
||||
}
|
||||
|
||||
void load_scene_additive(const char* file) {
|
||||
printf("parsing scene\n");
|
||||
_parse_scene(file);
|
||||
printf("parsed scene\n");
|
||||
}
|
|
@ -3,7 +3,20 @@
|
|||
|
||||
#include "memory.h"
|
||||
|
||||
typedef struct object_t object_t;
|
||||
|
||||
typedef void(*type_handler_fn)(object_t* this, int argc, char** argv);
|
||||
|
||||
// Add or replace the type handler for [Object] entries of a given key.
|
||||
// Will delete the handler entry if handler == NULL.
|
||||
void set_type_handler(const char* type, type_handler_fn handler);
|
||||
|
||||
// Load a scene exclusively. Clears the current scene before parsing file.
|
||||
void load_scene(const char* file);
|
||||
|
||||
// Load a scene additively.
|
||||
// Will not clear the currently active objects before parsing file.
|
||||
void load_scene_additive(const char* file);
|
||||
|
||||
#endif /* _corelib_scene_h */
|
||||
|
||||
|
|
Loading…
Reference in New Issue