#ifndef MATADOR_COLLECTION_PROXY_HPP #define MATADOR_COLLECTION_PROXY_HPP #include "matador/object/collection_resolver.hpp" #include "matador/utils/identifier.hpp" #include #include #include namespace matador::object { template class collection_proxy final { public: collection_proxy() = default; // Lazy collection_proxy(std::weak_ptr> resolver, utils::identifier owner_id) : owner_id_(std::move(owner_id)), resolver_(std::move(resolver)) {} // Eager collection_proxy(std::weak_ptr> resolver, std::vector items) : items_(std::move(items)), resolver_(std::move(resolver)) {} // Transient explicit collection_proxy(std::vector items) : items_(std::move(items)) {} [[nodiscard]] const utils::identifier& owner_id() const { return owner_id_; } const std::vector& items() const { resolve(); return items_; } std::vector& items() { resolve(); return items_; } private: void resolve() { if (loaded_) { return; } std::lock_guard lock(mutex_); auto resolver = resolver_.lock(); if (!resolver) { return; // Todo: Add states (Detached, Attached, Transient) - if attached an no resolver is available throw runtime exception // throw std::runtime_error("Detached proxy (session expired)"); } items_ = resolver->resolve(owner_id_); loaded_ = true; } private: const utils::identifier owner_id_; std::atomic_bool loaded_{false}; std::vector items_; std::weak_ptr> resolver_{}; mutable std::mutex mutex_{}; }; } #endif //MATADOR_COLLECTION_PROXY_HPP