#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 ViewType create(Args&&... args) { if (enabled_ && count() >= step_ * lastCleanup_) collect(); std::unique_ptr object(new ViewType(std::forward(args)...)); auto copy = *object; std::lock_guard g(lock_); objects_.emplace(object->handle(), std::move(object)); return copy; } template ObjectType get(GCHandle 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_; double step_; std::unordered_map> objects_; private: GC(); GC(GC&&) = delete; GC(const GC&) = delete; void collect(); void pause() { enabled_ = false; } void resume() { enabled_ = true; } double step() const { return step_; } void step(double newStep) { step_ = newStep; } bool enabled() { return enabled_; } size_t count() const; }; } // effil