(#394) Introduce Script entity
parent
b4d072d809
commit
101b1597a2
|
@ -103,6 +103,8 @@ add_executable(nothing
|
|||
src/game/level/regions.h
|
||||
src/system/line_stream.h
|
||||
src/system/line_stream.c
|
||||
src/game/level/script.h
|
||||
src/game/level/script.c
|
||||
)
|
||||
|
||||
add_executable(repl
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "game/level/physical_world.h"
|
||||
#include "game/level/platforms.h"
|
||||
#include "game/level/player.h"
|
||||
#include "game/level/regions.h"
|
||||
#include "system/error.h"
|
||||
#include "system/line_stream.h"
|
||||
#include "system/lt.h"
|
||||
|
@ -32,6 +33,7 @@ struct Level
|
|||
Background *background;
|
||||
Boxes *boxes;
|
||||
Labels *labels;
|
||||
Regions *regions;
|
||||
};
|
||||
|
||||
Level *create_level_from_file(const char *file_name)
|
||||
|
@ -124,6 +126,14 @@ Level *create_level_from_file(const char *file_name)
|
|||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
level->regions = PUSH_LT(
|
||||
lt,
|
||||
create_regions_from_line_stream(level_stream),
|
||||
destroy_regions);
|
||||
if (level->regions == NULL) {
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
level->physical_world = PUSH_LT(lt, create_physical_world(), destroy_physical_world);
|
||||
if (level->physical_world == NULL) {
|
||||
RETURN_LT(lt, NULL);
|
||||
|
|
|
@ -2,106 +2,94 @@
|
|||
|
||||
#include "player.h"
|
||||
#include "regions.h"
|
||||
#include "script.h"
|
||||
#include "script/gc.h"
|
||||
#include "script/interpreter.h"
|
||||
#include "script/parser.h"
|
||||
#include "script/scope.h"
|
||||
#include "str.h"
|
||||
#include "system/error.h"
|
||||
#include "system/lt.h"
|
||||
#include "system/line_stream.h"
|
||||
#include "system/lt.h"
|
||||
|
||||
/* TODO(#394): regions is not integrated with the level format */
|
||||
struct Regions
|
||||
{
|
||||
Lt *lt;
|
||||
Rect rect;
|
||||
Gc *gc;
|
||||
struct Scope scope;
|
||||
size_t count;
|
||||
Rect *rects;
|
||||
Script **scripts;
|
||||
};
|
||||
|
||||
Regions *create_regions(Rect rect, const char *script_src)
|
||||
Regions *create_regions_from_line_stream(LineStream *line_stream)
|
||||
{
|
||||
assert(script_src);
|
||||
assert(line_stream);
|
||||
|
||||
Lt *lt = create_lt();
|
||||
if (lt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Regions *regions = PUSH_LT(lt, malloc(sizeof(Regions)), free);
|
||||
if (regions != NULL) {
|
||||
Regions *regions = PUSH_LT(
|
||||
lt,
|
||||
malloc(sizeof(Regions)),
|
||||
free);
|
||||
if (regions == NULL) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
regions->lt = lt;
|
||||
regions->rect = rect;
|
||||
|
||||
regions->gc = PUSH_LT(lt, create_gc(), destroy_gc);
|
||||
if (regions->gc == NULL) {
|
||||
if(sscanf(
|
||||
line_stream_next(line_stream),
|
||||
"%lu",
|
||||
®ions->count) < 0) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
regions->scope = create_scope(regions->gc);
|
||||
regions->rects = PUSH_LT(
|
||||
lt,
|
||||
malloc(sizeof(Rect) * regions->count),
|
||||
free);
|
||||
if (regions->rects == NULL) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
while (*script_src != 0) {
|
||||
struct ParseResult parse_result = read_expr_from_string(regions->gc, script_src);
|
||||
if (parse_result.is_error) {
|
||||
fprintf(stderr, "Parsing error: %s\n", parse_result.error_message);
|
||||
regions->scripts = PUSH_LT(
|
||||
lt,
|
||||
malloc(sizeof(Script*) * regions->count),
|
||||
free);
|
||||
if (regions->scripts == NULL) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
printf("Amount of regions: %lu\n", regions->count);
|
||||
|
||||
for (size_t i = 0; i < regions->count; ++i) {
|
||||
if (sscanf(
|
||||
line_stream_next(line_stream),
|
||||
"%f%f%f%f",
|
||||
®ions->rects[i].x,
|
||||
®ions->rects[i].y,
|
||||
®ions->rects[i].w,
|
||||
®ions->rects[i].h) < 0) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
struct EvalResult eval_result = eval(
|
||||
regions->gc,
|
||||
®ions->scope,
|
||||
parse_result.expr);
|
||||
if (eval_result.is_error) {
|
||||
fprintf(stderr, "Evaluation error: ");
|
||||
print_expr_as_sexpr(stderr, eval_result.expr);
|
||||
regions->scripts[i] = PUSH_LT(
|
||||
lt,
|
||||
create_script_from_line_stream(line_stream),
|
||||
destroy_script);
|
||||
if (regions->scripts[i] == NULL) {
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
script_src = next_token(parse_result.end).begin;
|
||||
}
|
||||
|
||||
/* TODO(#405): regions does not check if the script provides on-enter and on-leave callbacks */
|
||||
|
||||
return regions;
|
||||
}
|
||||
|
||||
Regions *create_regions_from_stream(LineStream *line_stream)
|
||||
{
|
||||
assert(line_stream);
|
||||
|
||||
Rect rect;
|
||||
|
||||
if (sscanf(
|
||||
line_stream_next(line_stream),
|
||||
"%f%f%f%f",
|
||||
&rect.x, &rect.y,
|
||||
&rect.w, &rect.h) < 0) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t n;
|
||||
if (sscanf(
|
||||
line_stream_next(line_stream),
|
||||
"%lu\n",
|
||||
&n) < 0) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: script is not read */
|
||||
char *script = NULL;
|
||||
|
||||
Regions *regions = create_regions(rect, script);
|
||||
if (regions == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(script);
|
||||
/* TODO: create_regions_from_line_stream doesn't check if the scripts contain proper callbacks */
|
||||
|
||||
return regions;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ typedef struct Regions Regions;
|
|||
typedef struct Player Player;
|
||||
typedef struct LineStream LineStream;
|
||||
|
||||
Regions *create_regions(Rect rect, const char *script_src);
|
||||
Regions *create_regions_from_stream(LineStream *line_stream);
|
||||
Regions *create_regions_from_line_stream(LineStream *line_stream);
|
||||
void destroy_regions(Regions *regions);
|
||||
|
||||
void regions_player_enter(Regions *regions, Player *player);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "script.h"
|
||||
#include "system/line_stream.h"
|
||||
|
||||
/* TODO: script entity clashes with script/ subpackage */
|
||||
/* TODO: script entity is not implemented */
|
||||
|
||||
Script *create_script_from_line_stream(LineStream *line_stream)
|
||||
{
|
||||
assert(line_stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void destroy_script(Script *script)
|
||||
{
|
||||
assert(script);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef SCRIPT_H_
|
||||
#define SCRIPT_H_
|
||||
|
||||
typedef struct Script Script;
|
||||
typedef struct LineStream LineStream;
|
||||
|
||||
Script *create_script_from_line_stream(LineStream *line_stream);
|
||||
void destroy_script(Script *script);
|
||||
|
||||
#endif // SCRIPT_H_
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef LINE_STREAM_H_
|
||||
#define LINE_STREAM_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct LineStream LineStream;
|
||||
|
||||
LineStream *create_line_stream(const char *filename,
|
||||
|
|
Loading…
Reference in New Issue