code: armageddon
parent
172dbaeda7
commit
1705d97620
|
@ -9,7 +9,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
include_directories(eco2d-cli code/vendors code/common)
|
include_directories(eco2d-cli code/vendors code/common)
|
||||||
include_directories(eco2d-client code/vendors code/common)
|
include_directories(eco2d-client code/vendors code/common)
|
||||||
include_directories(eco2d-server code/vendors code/common)
|
include_directories(eco2d-server code/vendors code/vendors/flecs code/common)
|
||||||
|
|
||||||
add_subdirectory(code/apps/client)
|
add_subdirectory(code/apps/client)
|
||||||
add_subdirectory(code/apps/server)
|
add_subdirectory(code/apps/server)
|
||||||
|
|
|
@ -12,12 +12,16 @@ add_executable(eco2d-server
|
||||||
header/world/world.h
|
header/world/world.h
|
||||||
header/world/blocks.h
|
header/world/blocks.h
|
||||||
header/world/blocks_info.h
|
header/world/blocks_info.h
|
||||||
|
header/components/general.h
|
||||||
|
header/components/net.h
|
||||||
|
|
||||||
../../vendors/cwpack/cwpack.c
|
../../vendors/cwpack/cwpack.c
|
||||||
../../vendors/cwpack/cwpack.h
|
../../vendors/cwpack/cwpack.h
|
||||||
|
|
||||||
../../vendors/flecs/flecs.c
|
../../vendors/flecs/flecs.c
|
||||||
../../vendors/flecs/flecs.h
|
../../vendors/flecs/flecs.h
|
||||||
|
../../vendors/flecs/flecs_meta.c
|
||||||
|
../../vendors/flecs/flecs_meta.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(eco2d-server header)
|
include_directories(eco2d-server header)
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "flecs/flecs.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int16_t x, y;
|
|
||||||
} chunk;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float x, y;
|
|
||||||
} position;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t peer_id;
|
|
||||||
} netclient;
|
|
||||||
|
|
||||||
ECS_COMPONENT_DECLARE(chunk);
|
|
||||||
ECS_COMPONENT_DECLARE(position);
|
|
||||||
ECS_COMPONENT_DECLARE(netclient);
|
|
||||||
|
|
||||||
static inline void components_register(ecs_world_t *ecs) {
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, chunk);
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, position);
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, netclient);
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
#include "flecs/flecs.h"
|
||||||
|
#include "flecs/flecs_meta.h"
|
||||||
|
|
||||||
|
ECS_STRUCT(Chunk, {
|
||||||
|
int16_t x;
|
||||||
|
int16_t y;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_STRUCT(Position, {
|
||||||
|
int16_t x;
|
||||||
|
int16_t y;
|
||||||
|
});
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ECS_DECLARE_COMPONENT(Chunk);
|
||||||
|
ECS_DECLARE_COMPONENT(Position);
|
||||||
|
} Common;
|
||||||
|
|
||||||
|
#define CommonImportHandles(handles)\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, Chunk);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, Position);
|
||||||
|
|
||||||
|
static inline void CommonImport(ecs_world_t *ecs) {
|
||||||
|
ECS_MODULE(ecs, Common);
|
||||||
|
|
||||||
|
ecs_set_name_prefix(ecs, "Common");
|
||||||
|
|
||||||
|
ECS_IMPORT(ecs, FlecsMeta);
|
||||||
|
|
||||||
|
ECS_META(ecs, Chunk);
|
||||||
|
ECS_META(ecs, Position);
|
||||||
|
|
||||||
|
ECS_EXPORT_COMPONENT(Chunk);
|
||||||
|
ECS_EXPORT_COMPONENT(Position);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
#include "flecs/flecs.h"
|
||||||
|
#include "flecs/flecs_meta.h"
|
||||||
|
|
||||||
|
ECS_STRUCT(NetClient, {
|
||||||
|
uint16_t peer_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ECS_DECLARE_COMPONENT(NetClient);
|
||||||
|
} Net;
|
||||||
|
|
||||||
|
#define NetImportHandles(handles)\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, NetClient);\
|
||||||
|
|
||||||
|
static inline void NetImport(ecs_world_t *ecs) {
|
||||||
|
ECS_MODULE(ecs, Net);
|
||||||
|
|
||||||
|
ecs_set_name_prefix(ecs, "Net");
|
||||||
|
|
||||||
|
ECS_IMPORT(ecs, FlecsMeta);
|
||||||
|
|
||||||
|
ECS_META(ecs, NetClient);
|
||||||
|
|
||||||
|
ECS_EXPORT_COMPONENT(NetClient);
|
||||||
|
}
|
|
@ -9,9 +9,11 @@
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "components.h"
|
|
||||||
#include "world/world.h"
|
#include "world/world.h"
|
||||||
|
|
||||||
|
#include "components/general.h"
|
||||||
|
#include "components/net.h"
|
||||||
|
|
||||||
#define NETWORK_UPDATE_DELAY 0.100
|
#define NETWORK_UPDATE_DELAY 0.100
|
||||||
#define NETWORK_MAX_CLIENTS 32
|
#define NETWORK_MAX_CLIENTS 32
|
||||||
|
|
||||||
|
@ -59,6 +61,9 @@ int32_t network_server_stop(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t network_server_tick(void) {
|
int32_t network_server_tick(void) {
|
||||||
|
ECS_IMPORT(world_ecs(), Common);
|
||||||
|
ECS_IMPORT(world_ecs(), Net);
|
||||||
|
|
||||||
ENetEvent event = {0};
|
ENetEvent event = {0};
|
||||||
while (enet_host_service(server, &event, 1) > 0) {
|
while (enet_host_service(server, &event, 1) > 0) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
@ -67,8 +72,8 @@ int32_t network_server_tick(void) {
|
||||||
uint16_t peer_id = event.peer->incomingPeerID;
|
uint16_t peer_id = event.peer->incomingPeerID;
|
||||||
|
|
||||||
ecs_entity_t e = ecs_new(world_ecs(), 0);
|
ecs_entity_t e = ecs_new(world_ecs(), 0);
|
||||||
ecs_set(world_ecs(), e, position, {0, 0});
|
ecs_set(world_ecs(), e, Position, {0, 0});
|
||||||
ecs_set(world_ecs(), e, netclient, {peer_id});
|
ecs_set(world_ecs(), e, NetClient, {peer_id});
|
||||||
|
|
||||||
event.peer->data = (void*)((uint32_t)e);
|
event.peer->data = (void*)((uint32_t)e);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "zpl.h"
|
#include "zpl.h"
|
||||||
#include "librg.h"
|
#include "librg.h"
|
||||||
#include "components.h"
|
#include "components/general.h"
|
||||||
#include "world/world.h"
|
#include "world/world.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -69,7 +69,6 @@ int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint1
|
||||||
}
|
}
|
||||||
|
|
||||||
world.ecs = ecs_init();
|
world.ecs = ecs_init();
|
||||||
components_register(world.ecs);
|
|
||||||
|
|
||||||
world.tracker = librg_world_create();
|
world.tracker = librg_world_create();
|
||||||
|
|
||||||
|
@ -85,17 +84,17 @@ int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint1
|
||||||
librg_config_chunkamount_set(world.tracker, world_size, world_size, 1);
|
librg_config_chunkamount_set(world.tracker, world_size, world_size, 1);
|
||||||
librg_config_chunkoffset_set(world.tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID);
|
librg_config_chunkoffset_set(world.tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID);
|
||||||
|
|
||||||
|
ECS_IMPORT(world.ecs, Common);
|
||||||
|
|
||||||
for (int i = 0; i < chunk_size * chunk_size; ++i) {
|
for (int i = 0; i < chunk_size * chunk_size; ++i) {
|
||||||
ecs_entity_t e = ecs_new(world.ecs, 0);
|
ecs_entity_t e = ecs_new(world.ecs, 0);
|
||||||
ecs_set(world.ecs, e, chunk, {
|
ecs_set(world.ecs, e, Chunk, {
|
||||||
.x = i % chunk_size,
|
.x = i % chunk_size,
|
||||||
.y = i / chunk_size,
|
.y = i / chunk_size,
|
||||||
});
|
});
|
||||||
|
|
||||||
librg_entity_track(world.tracker, e);
|
librg_entity_track(world.tracker, e);
|
||||||
librg_entity_chunk_set(world.tracker, e, i);
|
librg_entity_chunk_set(world.tracker, e, i);
|
||||||
|
|
||||||
zpl_printf("creating chunk: #%lld %d %d\n", e, i % chunk_size, i / chunk_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, world_write_update);
|
// librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, world_write_update);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,688 @@
|
||||||
|
#define flecs_meta_STATIC
|
||||||
|
#ifndef FLECS_META_H
|
||||||
|
#define FLECS_META_H
|
||||||
|
|
||||||
|
/* This generated file contains includes for project dependencies */
|
||||||
|
/*
|
||||||
|
)
|
||||||
|
(.)
|
||||||
|
.|.
|
||||||
|
| |
|
||||||
|
_.--| |--._
|
||||||
|
.-'; ;`-'& ; `&.
|
||||||
|
\ & ; & &_/
|
||||||
|
|"""---...---"""|
|
||||||
|
\ | | | | | | | /
|
||||||
|
`---.|.|.|.---'
|
||||||
|
|
||||||
|
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||||
|
* dependencies will automatically show up in this file. Include bake_config.h
|
||||||
|
* in your main project file. Do not edit! */
|
||||||
|
|
||||||
|
#ifndef FLECS_META_BAKE_CONFIG_H
|
||||||
|
#define FLECS_META_BAKE_CONFIG_H
|
||||||
|
|
||||||
|
/* Headers of public dependencies */
|
||||||
|
#include <flecs.h>
|
||||||
|
|
||||||
|
/* Convenience macro for exporting symbols */
|
||||||
|
#ifndef flecs_meta_STATIC
|
||||||
|
#if flecs_meta_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__))
|
||||||
|
#define FLECS_META_API __declspec(dllexport)
|
||||||
|
#elif flecs_meta_EXPORTS
|
||||||
|
#define FLECS_META_API __attribute__((__visibility__("default")))
|
||||||
|
#elif defined _MSC_VER
|
||||||
|
#define FLECS_META_API __declspec(dllimport)
|
||||||
|
#else
|
||||||
|
#define FLECS_META_API
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define FLECS_META_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FLECS_LEGACY
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Utility macro's (do not use in code!)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define ECS_ENUM_BOOTSTRAP(name, ...)\
|
||||||
|
typedef enum name __VA_ARGS__ name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static const char * __##name##__ = #__VA_ARGS__
|
||||||
|
|
||||||
|
#define ECS_STRUCT_IMPL(name, descriptor, ...)\
|
||||||
|
typedef struct name __VA_ARGS__ name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {EcsStructType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}\
|
||||||
|
|
||||||
|
#define ECS_ENUM_IMPL(name, descriptor, ...)\
|
||||||
|
typedef enum name __VA_ARGS__ name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {EcsEnumType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}
|
||||||
|
|
||||||
|
#define ECS_BITMASK_IMPL(name, descriptor, ...)\
|
||||||
|
typedef enum name __VA_ARGS__ name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {EcsBitmaskType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}
|
||||||
|
|
||||||
|
#define ECS_STRUCT_C(T, ...) ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__)
|
||||||
|
#define ECS_ENUM_C(T, ...) ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__)
|
||||||
|
#define ECS_BITMASK_C(T, ...) ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define ECS_ARRAY(name, T, length)\
|
||||||
|
typedef T name[length];\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {EcsArrayType, sizeof(T) * length, ECS_ALIGNOF(T), "(" #T "," #length ")", NULL}
|
||||||
|
|
||||||
|
#define ECS_VECTOR(name, T)\
|
||||||
|
typedef ecs_vector_t *name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {EcsVectorType, sizeof(ecs_vector_t*), ECS_ALIGNOF(ecs_vector_t*), "(" #T ")", NULL}
|
||||||
|
|
||||||
|
#define ECS_MAP(name, K, T)\
|
||||||
|
typedef ecs_map_t *name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {EcsMapType, sizeof(ecs_map_t*), ECS_ALIGNOF(ecs_map_t*), "(" #K "," #T ")", NULL}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
// Unspecialized class (see below)
|
||||||
|
namespace flecs {
|
||||||
|
template <typename T>
|
||||||
|
class __meta__ { };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specialized C++ class that stores name and descriptor of type
|
||||||
|
#define ECS_META_CPP(T, kind, descr);\
|
||||||
|
namespace flecs {\
|
||||||
|
template<>\
|
||||||
|
class __meta__ <T> {\
|
||||||
|
public:\
|
||||||
|
static const char* name() {\
|
||||||
|
return #T;\
|
||||||
|
}\
|
||||||
|
static EcsMetaType descriptor() {\
|
||||||
|
return {kind, sizeof(T), ECS_ALIGNOF(T), descr, NULL};\
|
||||||
|
}\
|
||||||
|
};\
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Use these macro's to define types.
|
||||||
|
//// The API will automatically select the right macro's for C or C++
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
// C++
|
||||||
|
|
||||||
|
// Define a struct
|
||||||
|
#define ECS_STRUCT(T, ...)\
|
||||||
|
ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__);\
|
||||||
|
ECS_META_CPP(T, EcsStructType, #__VA_ARGS__)
|
||||||
|
|
||||||
|
// Define an enumeration
|
||||||
|
#define ECS_ENUM(T, ...)\
|
||||||
|
ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__);\
|
||||||
|
ECS_META_CPP(T, EcsEnumType, #__VA_ARGS__);
|
||||||
|
|
||||||
|
// Define a bitmask
|
||||||
|
#define ECS_BITMASK(T, ...)\
|
||||||
|
ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__);\
|
||||||
|
ECS_META_CPP(T, EcsBitmaskType, #__VA_ARGS__)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// C
|
||||||
|
|
||||||
|
// Define a struct
|
||||||
|
#define ECS_STRUCT(name, ...)\
|
||||||
|
ECS_STRUCT_IMPL(name, #__VA_ARGS__, __VA_ARGS__)
|
||||||
|
|
||||||
|
// Define an enumeration
|
||||||
|
#define ECS_ENUM(name, ...)\
|
||||||
|
ECS_ENUM_IMPL(name, #__VA_ARGS__, __VA_ARGS__)
|
||||||
|
|
||||||
|
// Define a bitmask
|
||||||
|
#define ECS_BITMASK(name, ...)\
|
||||||
|
ECS_BITMASK_IMPL(name, #__VA_ARGS__, __VA_ARGS__)
|
||||||
|
|
||||||
|
// Define a type alias
|
||||||
|
#define ECS_ALIAS(type, name)\
|
||||||
|
typedef type name;\
|
||||||
|
ECS_UNUSED \
|
||||||
|
static EcsMetaType __##name##__ = {0, sizeof(name), ECS_ALIGNOF(name), NULL, &__##type##__};\
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Use these macro's inside types
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Define a vector
|
||||||
|
#define ecs_vector(T) ecs_vector_t*
|
||||||
|
|
||||||
|
// Define a map
|
||||||
|
#define ecs_map(K, T) ecs_map_t*
|
||||||
|
|
||||||
|
// Indicate that members after this should not be serialized
|
||||||
|
#define ECS_PRIVATE
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Meta description types
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* Explicit string type */
|
||||||
|
typedef const char* ecs_string_t;
|
||||||
|
|
||||||
|
/* Explicit byte type */
|
||||||
|
typedef uint8_t ecs_byte_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
namespace flecs {
|
||||||
|
using string = ecs_string_t;
|
||||||
|
using byte = ecs_byte_t;
|
||||||
|
|
||||||
|
// Define a bitmask
|
||||||
|
// In C++ trying to assign multiple flags to a variable of an enum type will
|
||||||
|
// result in a compiler error. Use this template so that the serializer knows
|
||||||
|
// this value is a bitmask, while also keeping the compiler happy.
|
||||||
|
template<typename T>
|
||||||
|
using bitmask = int32_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ECS_ENUM_BOOTSTRAP( ecs_type_kind_t, {
|
||||||
|
EcsPrimitiveType,
|
||||||
|
EcsBitmaskType,
|
||||||
|
EcsEnumType,
|
||||||
|
EcsStructType,
|
||||||
|
EcsArrayType,
|
||||||
|
EcsVectorType,
|
||||||
|
EcsMapType
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_STRUCT( EcsMetaType, {
|
||||||
|
ecs_type_kind_t kind;
|
||||||
|
ecs_size_t size;
|
||||||
|
int16_t alignment;
|
||||||
|
const char *descriptor;
|
||||||
|
void *alias;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_ENUM( ecs_primitive_kind_t, {
|
||||||
|
EcsBool,
|
||||||
|
EcsChar,
|
||||||
|
EcsByte,
|
||||||
|
EcsU8,
|
||||||
|
EcsU16,
|
||||||
|
EcsU32,
|
||||||
|
EcsU64,
|
||||||
|
EcsI8,
|
||||||
|
EcsI16,
|
||||||
|
EcsI32,
|
||||||
|
EcsI64,
|
||||||
|
EcsF32,
|
||||||
|
EcsF64,
|
||||||
|
EcsUPtr,
|
||||||
|
EcsIPtr,
|
||||||
|
EcsString,
|
||||||
|
EcsEntity
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_STRUCT( EcsPrimitive, {
|
||||||
|
ecs_primitive_kind_t kind;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define EcsBitmask for both C and C++. Both representations are equivalent in
|
||||||
|
// memory, but allow for a nicer type-safe API in C++
|
||||||
|
#if defined(__cplusplus) && !defined(FLECS_NO_CPP)
|
||||||
|
ECS_STRUCT( EcsBitmask, {
|
||||||
|
flecs::map<int32_t, flecs::string> constants;
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
ECS_STRUCT( EcsBitmask, {
|
||||||
|
ecs_map(int32_t, ecs_string_t) constants;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define EcsEnum for both C and C++. Both representations are equivalent in
|
||||||
|
// memory, but allow for a nicer type-safe API in C++
|
||||||
|
#if defined(__cplusplus) && !defined(FLECS_NO_CPP)
|
||||||
|
ECS_STRUCT( EcsEnum, {
|
||||||
|
flecs::map<int32_t, flecs::string> constants;
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
ECS_STRUCT( EcsEnum, {
|
||||||
|
ecs_map(int32_t, ecs_string_t) constants;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ECS_STRUCT( EcsMember, {
|
||||||
|
char *name;
|
||||||
|
ecs_entity_t type;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define EcsStruct for both C and C++. Both representations are equivalent in
|
||||||
|
// memory, but allow for a nicer type-safe API in C++
|
||||||
|
#if defined(__cplusplus) && !defined(FLECS_NO_CPP)
|
||||||
|
ECS_STRUCT( EcsStruct, {
|
||||||
|
flecs::vector<EcsMember> members;
|
||||||
|
bool is_partial;
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
ECS_STRUCT( EcsStruct, {
|
||||||
|
ecs_vector(EcsMember) members;
|
||||||
|
bool is_partial;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ECS_STRUCT( EcsArray, {
|
||||||
|
ecs_entity_t element_type;
|
||||||
|
int32_t count;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_STRUCT( EcsVector, {
|
||||||
|
ecs_entity_t element_type;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_STRUCT( EcsMap, {
|
||||||
|
ecs_entity_t key_type;
|
||||||
|
ecs_entity_t element_type;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Type serializer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ECS_ENUM_C( ecs_type_op_kind_t, {
|
||||||
|
EcsOpHeader,
|
||||||
|
EcsOpPrimitive,
|
||||||
|
EcsOpEnum,
|
||||||
|
EcsOpBitmask,
|
||||||
|
EcsOpPush,
|
||||||
|
EcsOpPop,
|
||||||
|
EcsOpArray,
|
||||||
|
EcsOpVector,
|
||||||
|
EcsOpMap
|
||||||
|
});
|
||||||
|
|
||||||
|
typedef ecs_vector_t ecs_type_op_vector_t;
|
||||||
|
typedef ecs_vector_t ecs_constant_vector_t;
|
||||||
|
|
||||||
|
ECS_STRUCT_C( ecs_type_op_t, {
|
||||||
|
ecs_entity_t type;
|
||||||
|
ecs_type_op_kind_t kind;
|
||||||
|
ecs_size_t size; /* Size of value or element type if array or vector */
|
||||||
|
int16_t alignment; /* Alignment of value */
|
||||||
|
int32_t count; /* Number of elements (only used for arrays) */
|
||||||
|
int32_t offset; /* Offset of value */
|
||||||
|
const char *name; /* Name of value (only used for struct members) */
|
||||||
|
|
||||||
|
ECS_PRIVATE
|
||||||
|
|
||||||
|
/* Instruction-specific data */
|
||||||
|
union {
|
||||||
|
ecs_primitive_kind_t primitive;
|
||||||
|
ecs_ref_t constant;
|
||||||
|
ecs_ref_t collection;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
ecs_ref_t key;
|
||||||
|
ecs_ref_t element;
|
||||||
|
} map;
|
||||||
|
} is;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECS_STRUCT_C( EcsMetaTypeSerializer, {
|
||||||
|
ecs_vector(ecs_type_op_t) ops;
|
||||||
|
});
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Pretty printer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/** Convert value to a string. */
|
||||||
|
FLECS_META_API
|
||||||
|
char* ecs_ptr_to_str(
|
||||||
|
ecs_world_t *world,
|
||||||
|
ecs_entity_t type,
|
||||||
|
void* ptr);
|
||||||
|
|
||||||
|
/** Convert value to a string. */
|
||||||
|
FLECS_META_API
|
||||||
|
char* ecs_entity_to_str(
|
||||||
|
ecs_world_t *world,
|
||||||
|
ecs_entity_t entity);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Serialization utilities
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define ECS_MAX_I8 127
|
||||||
|
#define ECS_MIN_I8 -128
|
||||||
|
|
||||||
|
#define ECS_MAX_I16 32767
|
||||||
|
#define ECS_MIN_I16 -32768
|
||||||
|
|
||||||
|
#define ECS_MAX_I32 2147483647
|
||||||
|
#define ECS_MIN_I32 -2147483648
|
||||||
|
|
||||||
|
#define ECS_MAX_I64 9223372036854775807
|
||||||
|
#define ECS_MIN_I64 (-9223372036854775807 - 1)
|
||||||
|
|
||||||
|
#define ECS_MAX_U8 255u
|
||||||
|
#define ECS_MAX_U16 65535u
|
||||||
|
#define ECS_MAX_U32 4294967295u
|
||||||
|
#define ECS_MAX_U64 18446744073709551615u
|
||||||
|
|
||||||
|
#define ECS_MAX_I8_STR "127"
|
||||||
|
#define ECS_MIN_I8_STR "-128"
|
||||||
|
|
||||||
|
#define ECS_MAX_I16_STR "32767"
|
||||||
|
#define ECS_MIN_I16_STR "-32768"
|
||||||
|
|
||||||
|
#define ECS_MAX_I32_STR "2147483647"
|
||||||
|
#define ECS_MIN_I32_STR "-2147483648"
|
||||||
|
|
||||||
|
#define ECS_MAX_I64_STR "9223372036854775807"
|
||||||
|
#define ECS_MIN_I64_STR "-9223372036854775808"
|
||||||
|
|
||||||
|
#define ECS_MAX_U8_STR "255"
|
||||||
|
#define ECS_MAX_U16_STR "65535"
|
||||||
|
#define ECS_MAX_U32_STR "4294967295"
|
||||||
|
#define ECS_MAX_U64_STR "18446744073709551615"
|
||||||
|
|
||||||
|
/** Escape a character */
|
||||||
|
FLECS_META_API
|
||||||
|
char* ecs_chresc(
|
||||||
|
char *out,
|
||||||
|
char in,
|
||||||
|
char delimiter);
|
||||||
|
|
||||||
|
/** Parse an escaped character */
|
||||||
|
FLECS_META_API
|
||||||
|
const char* ecs_chrparse(
|
||||||
|
const char *in,
|
||||||
|
char *out);
|
||||||
|
|
||||||
|
/** Escape a string */
|
||||||
|
FLECS_META_API
|
||||||
|
ecs_size_t ecs_stresc(
|
||||||
|
char *out,
|
||||||
|
ecs_size_t n,
|
||||||
|
char delimiter,
|
||||||
|
const char *in);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Deserialization API
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define ECS_META_MAX_SCOPE_DEPTH (32) /* >32 levels of nesting is not sane */
|
||||||
|
|
||||||
|
typedef struct ecs_meta_scope_t {
|
||||||
|
ecs_entity_t type;
|
||||||
|
ecs_vector_t *ops;
|
||||||
|
int32_t start;
|
||||||
|
int32_t cur_op;
|
||||||
|
int32_t cur_elem;
|
||||||
|
int32_t count;
|
||||||
|
void *base;
|
||||||
|
ecs_vector_t *vector;
|
||||||
|
bool is_collection;
|
||||||
|
} ecs_meta_scope_t;
|
||||||
|
|
||||||
|
typedef struct ecs_meta_cursor_t {
|
||||||
|
ecs_world_t *world;
|
||||||
|
ecs_meta_scope_t scope[ECS_META_MAX_SCOPE_DEPTH];
|
||||||
|
int32_t depth;
|
||||||
|
} ecs_meta_cursor_t;
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
ecs_meta_cursor_t ecs_meta_cursor(
|
||||||
|
ecs_world_t *world,
|
||||||
|
ecs_entity_t type,
|
||||||
|
void *base);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
void* ecs_meta_get_ptr(
|
||||||
|
ecs_meta_cursor_t *cursor);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_next(
|
||||||
|
ecs_meta_cursor_t *cursor);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_move(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
int32_t pos);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_move_name(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_push(
|
||||||
|
ecs_meta_cursor_t *cursor);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_pop(
|
||||||
|
ecs_meta_cursor_t *cursor);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_bool(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
bool value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_char(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
char value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_int(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
int64_t value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_uint(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
uint64_t value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_float(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
double value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_string(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
const char *value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_entity(
|
||||||
|
ecs_meta_cursor_t *cursor,
|
||||||
|
ecs_entity_t value);
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
int ecs_meta_set_null(
|
||||||
|
ecs_meta_cursor_t *cursor);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Module implementation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct FlecsMeta {
|
||||||
|
ECS_DECLARE_COMPONENT(EcsPrimitive);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsEnum);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsBitmask);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsStruct);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsArray);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsVector);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsMap);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsMetaType);
|
||||||
|
ECS_DECLARE_COMPONENT(EcsMetaTypeSerializer);
|
||||||
|
} FlecsMeta;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
void FlecsMetaImport(
|
||||||
|
ecs_world_t *world);
|
||||||
|
|
||||||
|
#define FlecsMetaImportHandles(handles)\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsPrimitive);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsEnum);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsBitmask);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsStruct);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsArray);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsVector);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsMap);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsMetaType);\
|
||||||
|
ECS_IMPORT_COMPONENT(handles, EcsMetaTypeSerializer);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Macro for inserting metadata in C application
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
FLECS_META_API
|
||||||
|
void ecs_new_meta(
|
||||||
|
ecs_world_t *world,
|
||||||
|
ecs_entity_t component,
|
||||||
|
struct EcsMetaType *meta_type);
|
||||||
|
|
||||||
|
#define ECS_META(world, T)\
|
||||||
|
ECS_COMPONENT(world, T);\
|
||||||
|
ecs_new_meta(world, ecs_entity(T), &__##T##__);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// C++ Module implementation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#ifndef FLECS_NO_CPP
|
||||||
|
|
||||||
|
namespace flecs {
|
||||||
|
namespace components {
|
||||||
|
|
||||||
|
class meta {
|
||||||
|
public:
|
||||||
|
using Primitive = EcsPrimitive;
|
||||||
|
using Enum = EcsEnum;
|
||||||
|
using Bitmask = EcsBitmask;
|
||||||
|
using Struct = EcsStruct;
|
||||||
|
using Array = EcsArray;
|
||||||
|
using Vector = EcsVector;
|
||||||
|
using Type = EcsMetaType;
|
||||||
|
using TypeSerializer = EcsMetaTypeSerializer;
|
||||||
|
|
||||||
|
enum TypeKind {
|
||||||
|
PrimitiveType = EcsPrimitiveType,
|
||||||
|
BitmaskType = EcsBitmaskType,
|
||||||
|
EnumType = EcsEnumType,
|
||||||
|
StructType = EcsStructType,
|
||||||
|
ArrayType = EcsArrayType,
|
||||||
|
VectorType = EcsVectorType,
|
||||||
|
MapType = EcsMapType
|
||||||
|
};
|
||||||
|
|
||||||
|
meta(flecs::world& world) {
|
||||||
|
FlecsMetaImport(world.c_ptr());
|
||||||
|
|
||||||
|
flecs::module<flecs::components::meta>(world, "flecs::components::meta");
|
||||||
|
|
||||||
|
flecs::component<Primitive>(world, "EcsPrimitive");
|
||||||
|
flecs::component<Enum>(world, "EcsEnum");
|
||||||
|
flecs::component<Bitmask>(world, "EcsBitmask");
|
||||||
|
flecs::component<Struct>(world, "EcsStruct");
|
||||||
|
flecs::component<Array>(world, "EcsArray");
|
||||||
|
flecs::component<Vector>(world, "EcsVector");
|
||||||
|
flecs::component<Type>(world, "EcsMetaType");
|
||||||
|
flecs::component<TypeSerializer>(world, "EcsMetaTypeSerializer");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Functions for inserting metadata in C++ applications
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Template that injects metadata into ECS
|
||||||
|
template <typename T>
|
||||||
|
flecs::entity meta(flecs::world& world) {
|
||||||
|
flecs::entity e = flecs::component<T>(world, flecs::__meta__<T>::name());
|
||||||
|
e.set<EcsMetaType>({ flecs::__meta__<T>::descriptor() });
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Serialize values to string
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string pretty_print(flecs::world& world, flecs::entity_t type, T& data) {
|
||||||
|
char *str = ecs_ptr_to_str(world.c_ptr(), type, &data);
|
||||||
|
std::string result = std::string(str);
|
||||||
|
free(str);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string pretty_print(flecs::world& world, flecs::entity type, T& data) {
|
||||||
|
return pretty_print(world, type.id(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string pretty_print(flecs::world& world, T& data) {
|
||||||
|
entity_t type = _::component_info<T>::id();
|
||||||
|
return flecs::pretty_print(world, type, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline std::string pretty_print<flecs::entity>(flecs::world& world, flecs::entity& entity) {
|
||||||
|
char *str = ecs_entity_to_str(world.c_ptr(), entity.id());
|
||||||
|
std::string result = std::string(str);
|
||||||
|
free(str);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FLECS_NO_CPP
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif // FLECS_META_H
|
Loading…
Reference in New Issue