Skip to content

Instantly share code, notes, and snippets.

@eliasdaler
Last active June 5, 2021 03:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eliasdaler/f5c2ee50fc7e42bf3ee18ad7d46d18f8 to your computer and use it in GitHub Desktop.
Save eliasdaler/f5c2ee50fc7e42bf3ee18ad7d46d18f8 to your computer and use it in GitHub Desktop.
Safe reference implementation. C++ part. See https://eliasdaler.github.io/game-object-references for details
#include <sol.hpp>
#include <string>
#include <iostream>
using EntityId = int;
class Entity {
public:
explicit Entity(EntityId id) :
name("John"), id(id)
{}
const std::string& getName() const { return name; }
void setName(const std::string& n) { name = n; }
EntityId getId() const { return id; }
private:
std::string name;
EntityId id;
};
sol::state lua; // globals are bad, but we'll use it for simpler implementation
class EntityManager {
public:
EntityManager() : idCounter(0) {}
Entity& createEntity()
{
auto id = idCounter;
++idCounter;
auto inserted = entities.emplace(id, std::make_unique<Entity>(id));
auto it = inserted.first; // iterator to created id/Entity pair
auto& e = *it->second; // created entity
lua["createHandle"](e);
return e;
}
void removeEntity(EntityId id)
{
lua["onEntityRemoved"](id);
entities.erase(id);
}
private:
std::unordered_map<EntityId, std::unique_ptr<Entity>> entities;
EntityId idCounter;
};
int main()
{
lua.open_libraries();
lua.new_usertype<Entity>("Entity",
"getName", &Entity::getName,
"setName", &Entity::setName,
"getId", &Entity::getId);
lua.do_file("safe_reference.lua");
EntityManager entityManager;
auto& entity = entityManager.createEntity();
lua["test"](entity);
std::cout << "Testing bad reference" << std::endl;
lua["testBadReference"](entity);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment