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"
|
#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 */
|
#endif /* _corelib_scene_h */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue