#pragma once
/*
GameEngine and Editor
by John Ryland
Copyright (c) 2023
*/
////////////////////////////////////////////////////////////////////////////////////
// Game State
#include "SchemaFile.h"
#include <cstdio>
#include <vector>
#include <deque>
#include <string>
#include <unordered_map>
namespace GameEngine {
// In the editor we want to have the appearance of editing component types, however
// in reality each edit creates a new component type and the existing component type is disabled
// Aliases of some common std types
template <typename T>
using Array = std::vector<T>;
template <typename T>
using List = std::deque<T>;
template <typename K, typename T>
using Map = std::unordered_map<K,T>;
using String = std::string;
using StringList = Array<String>;
template <typename T>
using Dict = Map<String,T>;
// Game state types
using EntityId = uint64_t;
using ComponentTypeId = uint64_t;
// Not intended for use during runtime
struct ComponentInstanceRef
{
ComponentTypeId componentId;
//EntityId entityId;
void* data;
};
const size_t MIN_COMPONENT_SIZE = sizeof(EntityId);
const size_t MAX_COMPONENT_SIZE = 1000; // Overhead of 24 bytes for the pool so each ComponentPoolData is 1024 bytes
const size_t MAX_COMPONENTS_PER_POOL = MAX_COMPONENT_SIZE / MIN_COMPONENT_SIZE;
struct ComponentPoolData
{
uint64_t occupied[(MAX_COMPONENTS_PER_POOL + 63) / 64];
uint32_t count;
uint32_t reserved;
uint8_t data[MAX_COMPONENT_SIZE];
};
const size_t COMPONENT_POOL_SIZE = sizeof(ComponentPoolData);
struct ComponentPool
{
List<ComponentPoolData> data;
};
// Not intended for use during runtime
struct ComponentType
{
ComponentTypeId id;
String name;
GameRuntime::StructDescription fields;
size_t size;
Array<EntityId> entities;
ComponentPool data;
bool enabled;
};
// Not intended for use during runtime
struct EntityRef
{
EntityId id;
//Array<ComponentInstanceRef> components;
Map<ComponentTypeId,void*> components;
};
// Not intended for use during runtime
using ComponentTypes = Map<ComponentTypeId,ComponentType>;
using Entities = Map<EntityId,EntityRef>;
const EntityId INVALID_ENTITY_ID = UINT64_MAX;
const ComponentTypeId INVALID_COMPONENT_TYPE_ID = UINT64_MAX;
class GameState
{
public:
GameState(GameRuntime::Schema* schema);
void RegisterComponentType();
StringList AllComponentTypeNames();
ComponentTypeId FindComponentTypeByName(String componentName);
GameRuntime::Schema* Schema();
void NewEntity();
void NewComponent();
void RemoveStaleComponentReferences();
private:
EntityId lastUsedEntityId = 0;
ComponentTypeId lastUsedComponentTypeId = 0;
GameRuntime::Schema* schema;
Entities entities;
ComponentTypes components;
};
} // GameEngine namespace