#pragma once #include "gc-object.h" #include #include #include #include namespace effil { class GC { public: // global gc instance static GC& instance(); static sol::table exportAPI(sol::state_view& lua); // This method is used to create all managed objects. template ObjectType create(Args&&... args) { if (enabled_ && lastCleanup_.fetch_add(1) == step_) collect(); auto object = std::make_unique(std::forward(args)...); auto copy = *object; std::lock_guard g(lock_); objects_.emplace(object->handle(), std::move(object)); return copy; } template ObjectType get(GCObjectHandle handle) { std::lock_guard g(lock_); auto it = objects_.find(handle); assert(it != objects_.end()); auto result = dynamic_cast(it->second.get()); assert(result); return *result; } private: mutable std::mutex lock_; bool enabled_; std::atomic lastCleanup_; size_t step_; std::unordered_map> objects_; private: GC(); GC(GC&&) = delete; GC(const GC&) = delete; void collect(); size_t size() const; void pause() { enabled_ = false; } void resume() { enabled_ = true; } size_t step() const { return step_; } void step(size_t newStep) { step_ = newStep; } bool enabled() { return enabled_; } size_t count(); }; } // effil