From a8470ab6a36edf7cd79506c3bc60cc6c11aefa3f Mon Sep 17 00:00:00 2001 From: Max Roncace Date: Sat, 13 Jul 2024 23:01:44 -0400 Subject: [PATCH] resman: Add C ABI --- .../include/argus/resman/cabi/resource.h | 67 ++++++++ .../argus/resman/cabi/resource_event.h | 45 +++++ .../argus/resman/cabi/resource_loader.h | 83 +++++++++ .../argus/resman/cabi/resource_manager.h | 68 ++++++++ .../static/resman/include/argus/resman_cabi.h | 22 +++ engine/static/resman/src/cabi/resource.cpp | 78 +++++++++ .../static/resman/src/cabi/resource_event.cpp | 56 ++++++ .../resman/src/cabi/resource_loader.cpp | 162 ++++++++++++++++++ .../resman/src/cabi/resource_manager.cpp | 92 ++++++++++ 9 files changed, 673 insertions(+) create mode 100644 engine/static/resman/include/argus/resman/cabi/resource.h create mode 100644 engine/static/resman/include/argus/resman/cabi/resource_event.h create mode 100644 engine/static/resman/include/argus/resman/cabi/resource_loader.h create mode 100644 engine/static/resman/include/argus/resman/cabi/resource_manager.h create mode 100644 engine/static/resman/include/argus/resman_cabi.h create mode 100644 engine/static/resman/src/cabi/resource.cpp create mode 100644 engine/static/resman/src/cabi/resource_event.cpp create mode 100644 engine/static/resman/src/cabi/resource_loader.cpp create mode 100644 engine/static/resman/src/cabi/resource_manager.cpp diff --git a/engine/static/resman/include/argus/resman/cabi/resource.h b/engine/static/resman/include/argus/resman/cabi/resource.h new file mode 100644 index 00000000..a5d57332 --- /dev/null +++ b/engine/static/resman/include/argus/resman/cabi/resource.h @@ -0,0 +1,67 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *argus_resource_t; +typedef const void *argus_resource_const_t; + +typedef struct argus_resource_prototype_t { + const char *uid; + const char *media_type; + const char *fs_path; +} argus_resource_prototype_t; + +typedef enum ResourceErrorReason { + RESOURCE_ERROR_REASON_GENERIC, + RESOURCE_ERROR_REASON_NOT_FOUND, + RESOURCE_ERROR_REASON_NOT_LOADED, + RESOURCE_ERROR_REASON_ALREADY_LOADED, + RESOURCE_ERROR_REASON_NO_LOADER, + RESOURCE_ERROR_REASON_LOAD_FAILED, + RESOURCE_ERROR_REASON_MALFORMED_CONTENT, + RESOURCE_ERROR_REASON_INVALID_CONTENT, + RESOURCE_ERROR_REASON_UNSUPPORTED_CONTENT, + RESOURCE_ERROR_REASON_UNEXPECTED_REFERENCE_TYPE, +} ResourceErrorReason; + +typedef void *argus_resource_error_t; + +argus_resource_prototype_t argus_resource_get_prototype(argus_resource_const_t resource); + +void argus_resource_release(argus_resource_const_t resource); + +const void *argus_resource_get_data_ptr(argus_resource_const_t resource); + +argus_resource_error_t argus_resource_error_new(ResourceErrorReason reason, const char *uid, const char *info); + +void argus_resource_error_destruct(argus_resource_error_t error); + +ResourceErrorReason argus_resource_error_get_reason(argus_resource_error_t error); + +const char *argus_resource_error_get_uid(argus_resource_error_t error); + +const char *argus_resource_error_get_info(argus_resource_error_t error); + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/include/argus/resman/cabi/resource_event.h b/engine/static/resman/include/argus/resman/cabi/resource_event.h new file mode 100644 index 00000000..f1f4b8f3 --- /dev/null +++ b/engine/static/resman/include/argus/resman/cabi/resource_event.h @@ -0,0 +1,45 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "argus/resman/cabi/resource.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const char *k_event_type_resource = "resource"; + +typedef enum ResourceEventType { + RESOURCE_EVENT_TYPE_LOAD, + RESOURCE_EVENT_TYPE_UNLOAD, +} ResourceEventType; + +typedef void *argus_resource_event_t; +typedef const void *argus_resource_event_const_t; + +ResourceEventType argus_resource_event_get_subtype(argus_resource_event_const_t event); + +const argus_resource_prototype_t argus_resource_event_get_prototype(argus_resource_event_const_t event); + +argus_resource_t argus_resource_event_get_resource(argus_resource_event_t event); + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/include/argus/resman/cabi/resource_loader.h b/engine/static/resman/include/argus/resman/cabi/resource_loader.h new file mode 100644 index 00000000..17508bb8 --- /dev/null +++ b/engine/static/resman/include/argus/resman/cabi/resource_loader.h @@ -0,0 +1,83 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "argus/resman/cabi/resource_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *argus_resource_loader_t; +typedef const void *argus_resource_loader_const_t; + +typedef struct VoidPtrOrResourceError { + bool is_ok; + union { + void *value; + argus_resource_error_t error; + } ve; +} VoidPtrOrResourceError; + +typedef void *argus_loaded_dependency_set_t; + +typedef struct LoadedDependencySetOrResourceError { + bool is_ok; + union { + argus_loaded_dependency_set_t value; + argus_resource_error_t error; + } ve; +} LoadedDependencySetOrResourceError; + +typedef bool (*argus_resource_read_callback_t)(void *dst, size_t len, + void *data); + +typedef VoidPtrOrResourceError (*argus_resource_load_fn_t)(argus_resource_loader_t loader, + argus_resource_manager_t manager, argus_resource_prototype_t proto, + argus_resource_read_callback_t read_callback, size_t size, void *user_data, void *engine_data); + +typedef VoidPtrOrResourceError (*argus_resource_copy_fn_t)(argus_resource_loader_t loader, + argus_resource_manager_t manager, argus_resource_prototype_t proto, + void *src, void *data); + +typedef void (*argus_resource_unload_fn_t)(argus_resource_loader_t loader, void *ptr, void *user_data); + +argus_resource_loader_t argus_resource_loader_new( + const char *const *media_types, + size_t media_types_count, + argus_resource_load_fn_t load_fn, + argus_resource_copy_fn_t copy_fn, + argus_resource_unload_fn_t unload_fn, + void *user_data +); + +LoadedDependencySetOrResourceError argus_resource_loader_load_dependencies(argus_resource_loader_t loader, + argus_resource_manager_t manager, const char *const *dependencies, size_t dependencies_count); + +size_t argus_loaded_dependency_set_get_count(argus_loaded_dependency_set_t set); + +const char *argus_loaded_dependency_set_get_name_at(argus_loaded_dependency_set_t set, size_t index); + +argus_resource_const_t argus_loaded_dependency_set_get_resource_at(argus_loaded_dependency_set_t set, size_t index); + +void argus_loaded_dependency_set_destruct(argus_loaded_dependency_set_t set); + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/include/argus/resman/cabi/resource_manager.h b/engine/static/resman/include/argus/resman/cabi/resource_manager.h new file mode 100644 index 00000000..e745d050 --- /dev/null +++ b/engine/static/resman/include/argus/resman/cabi/resource_manager.h @@ -0,0 +1,68 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "argus/resman/cabi/resource.h" + +#include +#include + +typedef void *argus_resource_manager_t; +typedef const void *argus_resource_manager_const_t; + +typedef void *argus_resource_loader_t; + +typedef struct ResourceOrResourceError { + bool is_ok; + union { + argus_resource_t value; + argus_resource_error_t error; + } ve; +} ResourceOrResourceError; + +argus_resource_manager_t argus_resource_manager_get_instance(void); + +void argus_resource_manager_discover_resources(argus_resource_manager_t mgr); + +void argus_resource_manager_add_memory_package(argus_resource_manager_t mgr, const unsigned char *buf, size_t len); + +void argus_resource_manager_register_loader(argus_resource_manager_t mgr, const char *const *media_types, + size_t media_types_count, argus_resource_loader_t loader); + +//TODO: register_extension_mappings + +ResourceOrResourceError argus_resource_manager_get_resource(argus_resource_manager_t mgr, const char *uid); + +ResourceOrResourceError argus_resource_manager_get_resource_weak(argus_resource_manager_t mgr, const char *uid); + +ResourceOrResourceError argus_resource_manager_try_get_resource(argus_resource_manager_t mgr, const char *uid); + +void argus_resource_manager_get_resource_async(argus_resource_manager_t mgr, const char *uid, + void(*callback)(ResourceOrResourceError)); + +ResourceOrResourceError argus_resource_manager_create_resource(argus_resource_manager_t mgr, const char *uid, + const char *media_type, const void *data, size_t len); + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/include/argus/resman_cabi.h b/engine/static/resman/include/argus/resman_cabi.h new file mode 100644 index 00000000..326dd382 --- /dev/null +++ b/engine/static/resman/include/argus/resman_cabi.h @@ -0,0 +1,22 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "argus/resman/cabi/resource.h" +#include "argus/resman/cabi/resource_event.h" +#include "argus/resman/cabi/resource_loader.h" +#include "argus/resman/cabi/resource_manager.h" diff --git a/engine/static/resman/src/cabi/resource.cpp b/engine/static/resman/src/cabi/resource.cpp new file mode 100644 index 00000000..af474645 --- /dev/null +++ b/engine/static/resman/src/cabi/resource.cpp @@ -0,0 +1,78 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "argus/resman/cabi/resource.h" + +#include "argus/resman/resource.hpp" +#include "argus/resman/resource_manager.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + +using argus::Resource; +using argus::ResourceError; + +static inline const Resource &_as_ref(argus_resource_const_t ptr) { + return *reinterpret_cast(ptr); +} + +static inline ResourceError &_error_as_ref(argus_resource_error_t &error) { + return *reinterpret_cast(error); +} + +argus_resource_prototype_t argus_resource_get_prototype(argus_resource_const_t resource) { + auto cpp_proto = _as_ref(resource).prototype; + return argus_resource_prototype_t { + cpp_proto.uid.c_str(), + cpp_proto.media_type.c_str(), + cpp_proto.fs_path.c_str(), + }; +} + +void argus_resource_release(argus_resource_const_t resource) { + _as_ref(resource).release(); +} + +argus_resource_error_t argus_resource_error_new(ResourceErrorReason reason, const char *uid, const char *info) { + return new argus::ResourceError { argus::ResourceErrorReason(reason), uid, info }; +} + +void argus_resource_error_destruct(argus_resource_error_t error) { + delete &_error_as_ref(error); +} + +const void *argus_resource_get_data_ptr(argus_resource_const_t resource) { + return _as_ref(resource).get_data_ptr(); +} + +ResourceErrorReason argus_resource_error_get_reason(argus_resource_error_t error) { + return ResourceErrorReason(_error_as_ref(error).reason); +} + +const char *argus_resource_error_get_uid(argus_resource_error_t error) { + return _error_as_ref(error).uid.c_str(); +} + +const char *argus_resource_error_get_info(argus_resource_error_t error) { + return _error_as_ref(error).info.c_str(); +} + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/src/cabi/resource_event.cpp b/engine/static/resman/src/cabi/resource_event.cpp new file mode 100644 index 00000000..2c009041 --- /dev/null +++ b/engine/static/resman/src/cabi/resource_event.cpp @@ -0,0 +1,56 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "argus/resman/cabi/resource_event.h" + +#include "argus/resman/resource_event.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + +using argus::ResourceEvent; + +static inline ResourceEvent &_as_ref(argus_resource_event_t ptr) { + return *reinterpret_cast(ptr); +} + +static inline const ResourceEvent &_as_ref(argus_resource_event_const_t ptr) { + return *reinterpret_cast(ptr); +} + +ResourceEventType argus_resource_event_get_subtype(argus_resource_event_const_t event) { + return ResourceEventType(_as_ref(event).subtype); +} + +const argus_resource_prototype_t argus_resource_event_get_prototype(argus_resource_event_const_t event) { + const auto &proto = _as_ref(event).prototype; + return argus_resource_prototype_t { + proto.uid.c_str(), + proto.media_type.c_str(), + proto.fs_path.c_str(), + }; +} + +argus_resource_t argus_resource_event_get_resource(argus_resource_event_t event) { + return _as_ref(event).resource; +} + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/src/cabi/resource_loader.cpp b/engine/static/resman/src/cabi/resource_loader.cpp new file mode 100644 index 00000000..e8231ce0 --- /dev/null +++ b/engine/static/resman/src/cabi/resource_loader.cpp @@ -0,0 +1,162 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "argus/resman/cabi/resource_loader.h" + +#include "argus/lowlevel/macros.hpp" + +#include "argus/resman/resource_loader.hpp" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +using argus::Resource; +using argus::ResourceError; +using argus::ResourceLoader; +using argus::ResourceManager; +using argus::ResourcePrototype; +using argus::Result; + +typedef std::vector> LoadedDependencySetImpl; + +static inline Result _unwrap_voidptr_result(VoidPtrOrResourceError res) { + if (res.is_ok) { + return argus::ok(res.ve.value); + } else { + ResourceError *unwrapped_err = reinterpret_cast(res.ve.error); + ResourceError err_copy = *unwrapped_err; + delete unwrapped_err; + return argus::err(err_copy); + } +} + +static LoadedDependencySetOrResourceError _wrap_dep_result( + Result, ResourceError> res) { + LoadedDependencySetOrResourceError wrapped_res; + wrapped_res.is_ok = res.is_ok(); + + if (res.is_ok()) { + const auto &map = res.unwrap(); + wrapped_res.ve.value = new LoadedDependencySetImpl(map.begin(), map.end()); + } else { + wrapped_res.ve.error = new ResourceError(res.unwrap_err()); + } + + return wrapped_res; +} + +static bool _read_callback(void *dst, size_t len, void *engine_data) { + auto &stream = *reinterpret_cast(engine_data); + stream.read(reinterpret_cast(dst), std::streamsize(len)); + return stream.good(); +} + +static const LoadedDependencySetImpl &_lds_as_ref(argus_loaded_dependency_set_t ptr) { + return *reinterpret_cast(ptr); +} + +class ProxiedResourceLoader : public ResourceLoader { + argus_resource_load_fn_t m_load_fn; + argus_resource_copy_fn_t m_copy_fn; + argus_resource_unload_fn_t m_unload_fn; + void *m_user_data; + + public: + ProxiedResourceLoader(std::vector media_types, + argus_resource_load_fn_t load_fn, + argus_resource_copy_fn_t copy_fn, + argus_resource_unload_fn_t unload_fn, void *user_data): + ResourceLoader(std::move(media_types)), + m_load_fn(load_fn), + m_copy_fn(copy_fn), + m_unload_fn(unload_fn), + m_user_data(user_data) { + //TODO + } + + Result load(ResourceManager &manager, const ResourcePrototype &proto, + std::istream &stream, size_t size) override { + auto wrapped_proto = argus_resource_prototype_t { + proto.uid.c_str(), + proto.media_type.c_str(), + proto.fs_path.c_str(), + }; + return _unwrap_voidptr_result(m_load_fn(this, &manager, wrapped_proto, _read_callback, size, + m_user_data, &stream)); + } + + Result copy(ResourceManager &manager, const ResourcePrototype &proto, + void *src, std::type_index type) override { + UNUSED(type); + auto wrapped_proto = argus_resource_prototype_t { + proto.uid.c_str(), + proto.media_type.c_str(), + proto.fs_path.c_str(), + }; + return _unwrap_voidptr_result(m_copy_fn(this, &manager, wrapped_proto, src, m_user_data)); + } + + void unload(void *data_ptr) override { + m_unload_fn(this, data_ptr, m_user_data); + } + + using ResourceLoader::load_dependencies; +}; + +argus_resource_loader_t argus_resource_loader_new( + const char *const *media_types, + size_t media_types_count, + argus_resource_load_fn_t load_fn, + argus_resource_copy_fn_t copy_fn, + argus_resource_unload_fn_t unload_fn, + void *user_data +) { + return new ProxiedResourceLoader(std::vector(media_types, media_types + media_types_count), + load_fn, copy_fn, unload_fn, user_data); +} + +LoadedDependencySetOrResourceError argus_resource_loader_load_dependencies(argus_resource_loader_t loader, + argus_resource_manager_t manager, const char *const *dependencies, size_t dependencies_count) { + auto &real_loader = *reinterpret_cast(loader); + auto &real_mgr = *reinterpret_cast(manager); + return _wrap_dep_result(real_loader.load_dependencies(real_mgr, + std::vector(dependencies, dependencies + dependencies_count))); +} + +size_t argus_loaded_dependency_set_get_count(argus_loaded_dependency_set_t set) { + return _lds_as_ref(set).size(); +} + +const char *argus_loaded_dependency_set_get_name_at(argus_loaded_dependency_set_t set, size_t index) { + return _lds_as_ref(set).at(index).first.c_str(); +} + +argus_resource_const_t argus_loaded_dependency_set_get_resource_at(argus_loaded_dependency_set_t set, size_t index) { + return _lds_as_ref(set).at(index).second; +} + +void argus_loaded_dependency_set_destruct(argus_loaded_dependency_set_t set) { + delete &_lds_as_ref(set); +} + +#ifdef __cplusplus +} +#endif diff --git a/engine/static/resman/src/cabi/resource_manager.cpp b/engine/static/resman/src/cabi/resource_manager.cpp new file mode 100644 index 00000000..da815119 --- /dev/null +++ b/engine/static/resman/src/cabi/resource_manager.cpp @@ -0,0 +1,92 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "argus/resman/cabi/resource_manager.h" + +#include "argus/lowlevel/result.hpp" + +#include "argus/resman/resource.hpp" +#include "argus/resman/resource_manager.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + +using argus::Result; + +using argus::Resource; +using argus::ResourceError; +using argus::ResourceManager; + +static inline ResourceManager &_as_ref(argus_resource_manager_t ptr) { + return *reinterpret_cast(ptr); +} + +static inline const ResourceOrResourceError _wrap_result(const Result &res) { + ResourceOrResourceError wrapped; + wrapped.is_ok = res.is_ok(); + if (res.is_ok()) { + wrapped.ve.value = &res.unwrap(); + } else { + wrapped.ve.error = argus_resource_error_t { new ResourceError(res.unwrap_err()) }; + } + return wrapped; +} + +argus_resource_manager_t argus_resource_manager_get_instance(void) { + return &ResourceManager::instance(); +} + +void argus_resource_manager_discover_resources(argus_resource_manager_t mgr) { + _as_ref(mgr).discover_resources(); +} + +void argus_resource_manager_add_memory_package(argus_resource_manager_t mgr, const unsigned char *buf, size_t len) { + _as_ref(mgr).add_memory_package(buf, len); +} + +//TODO: register_loader + +//TODO: register_extension_mappings + +ResourceOrResourceError argus_resource_manager_get_resource(argus_resource_manager_t mgr, const char *uid) { + return _wrap_result(_as_ref(mgr).get_resource(uid)); +} + +ResourceOrResourceError argus_resource_manager_get_resource_weak(argus_resource_manager_t mgr, const char *uid) { + return _wrap_result(_as_ref(mgr).get_resource_weak(uid)); +} + +ResourceOrResourceError argus_resource_manager_try_get_resource(argus_resource_manager_t mgr, const char *uid) { + return _wrap_result(_as_ref(mgr).try_get_resource(uid)); +} + +void argus_resource_manager_get_resource_async(argus_resource_manager_t mgr, const char *uid, + void(*callback)(ResourceOrResourceError)) { + _as_ref(mgr).get_resource_async(uid, + [callback](Result res) { callback(_wrap_result(res)); }); +} + +ResourceOrResourceError argus_resource_manager_create_resource(argus_resource_manager_t mgr, const char *uid, + const char *media_type, const void *data, size_t len) { + return _wrap_result(_as_ref(mgr).create_resource(uid, media_type, data, len)); +} + +#ifdef __cplusplus +} +#endif