(#394) Introduce Script entity

master
rexim 2018-10-26 23:07:36 +07:00
parent b4d072d809
commit 101b1597a2
7 changed files with 94 additions and 65 deletions

View File

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

View File

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

View File

@ -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",
&regions->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",
&regions->rects[i].x,
&regions->rects[i].y,
&regions->rects[i].w,
&regions->rects[i].h) < 0) {
throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, NULL);
}
struct EvalResult eval_result = eval(
regions->gc,
&regions->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;
}

View File

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

18
src/game/level/script.c Normal file
View File

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

10
src/game/level/script.h Normal file
View File

@ -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_

View File

@ -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,