added scene parsing

pull/14/head
Sara 2023-07-16 02:23:15 +02:00
parent 351c9ba713
commit 25c5f83fe4
2 changed files with 173 additions and 0 deletions

160
src/corelib/scene.c Normal file
View File

@ -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");
}

View File

@ -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 */