Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions include/gkit/core/object.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once

#include "gkit/core/object_id.hpp"

#include <concepts>
#include <memory>
#include <string>
#include <utility>

namespace gkit::core {
class Object;
Expand Down Expand Up @@ -39,5 +39,10 @@ namespace gkit::core {
static auto create(Args&&...) noexcept -> UniqueObject; */

virtual auto class_name() const -> std::string final;

[[nodiscard]] auto get_object_id() const noexcept -> const ObjectId& { return this->obj_id; }

protected:
ObjectId obj_id;
};
} // namespace gkit::core

@CoraBlack CoraBlack Aug 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要移动该文件

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace gkit::core {
try {
auto* obj_ptr = new T(std::forward(args)...);
auto obj_id = ObjectIdAllocator::instance().new_one();
obj_ptr->obj_id = obj_id;
this->id_instance_map.emplace(obj_id, obj_ptr);
return std::make_pair(std::move(obj_id), std::move(obj_ptr));
} catch (...) {
Expand Down
9 changes: 4 additions & 5 deletions include/gkit/core/processer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "gkit/scene/unit.hpp"

#include <atomic>
#include <memory>
#include <string>
#include <unordered_map>

Expand All @@ -17,12 +16,12 @@ namespace gkit {
auto run() -> void;
auto stop() -> void;

auto add_service_unit(std::string name, std::unique_ptr<scene::Unit>&& unit_ptr) noexcept -> void;
auto set_root(std::unique_ptr<scene::Unit>&& root_ptr) noexcept -> void;
auto add_service_unit(std::string name,core::UniqueObject&& unit_ptr) noexcept -> void;
auto set_root(core::UniqueObject&& root_ptr) noexcept -> void;

private:
std::unique_ptr<scene::Unit> root;
std::unordered_map<std::string, std::unique_ptr<scene::Unit>> service_units{};
core::UniqueObject root;
std::unordered_map<std::string, core::UniqueObject> service_units{};
std::atomic<bool> running = false;
}; // class Processer
} // namespace gkit
6 changes: 2 additions & 4 deletions include/gkit/core/unique_object.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "core/object_pool.hpp"
#include "gkit/core/object_pool.hpp"
#include "gkit/core/object.hpp"
#include "object_id.hpp"

Expand All @@ -10,7 +10,6 @@
namespace gkit::core {
class UniqueObject final {
Object* obj = nullptr;
ObjectId id;

UniqueObject() = default;

Expand All @@ -23,7 +22,7 @@ namespace gkit::core {

[[nodiscard]] auto get() -> Object* { return this->obj; }
[[nodiscard]] auto get() const -> const Object* { return this->obj; }
[[nodiscard]] inline auto get_id() const -> const ObjectId& { return this->id; }
[[nodiscard]] auto get_id() const noexcept -> const ObjectId&;

template<IsObject T, class... Args>
static auto create(Args&&... args) noexcept -> UniqueObject;
Expand All @@ -36,7 +35,6 @@ namespace gkit::core {
auto& obj_pool = ObjectPool::instance();
auto obj_opt = obj_pool.create<T>(std::forward(args)...);
if (obj_opt.has_value()) {
uobj.id = obj_opt->first;
uobj.obj = obj_opt->second;
}

Expand Down
2 changes: 1 addition & 1 deletion include/gkit/core/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace gkit::core {
class Value final {
public:
/**
* @brief Variant storage backing the Value. Object is held via std::unique_ptr
* @brief Variant storage backing the Value. Object is held via gkit::core::UniqueObject
* for exclusive ownership and automatic lifetime management.
*/
using Storage = std::variant<Null, Bool, Number, String, Array, Map, UniqueObject, ObjectId>;
Expand Down
55 changes: 29 additions & 26 deletions include/gkit/scene/unit.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#pragma once

#include "gkit/core/object.hpp"
#include "gkit/core/object_id.hpp"
#include "gkit/core/reflect/registry.hpp"
#include "gkit/core/unique_object.hpp"

#include <atomic>
#include <cstdint>
#include <functional>
#include <memory>
#include <iterator>
#include <mutex>
#include <optional>
#include <stdexcept>
Expand All @@ -32,9 +34,9 @@ namespace gkit::scene {
* class Unit
* @brief This is the gkit application unit. It is the basic unit of program composition.
* @note This class cannot be copied and constructed externally. If you want to create a unit,
* you should use the function @ref gkit::core::scene::Unit::create<T>().
* you should use the function @ref gkit::core::UniqueObject::create<T>().
*
* If you want to move an Unit instance, you should move with the std::unique_ptr by std::move().
* If you want to move an Unit instance, you should move with the gkit::core::UniqueObject by std::move().
*/
class Unit : public gkit::core::Object {
static gkit::core::reflect::RegistHolder register_holder;
Expand Down Expand Up @@ -103,7 +105,7 @@ namespace gkit::scene {
* be available after call @ref update_index_cache(), which will be happened when
* @ref process_handler() is called.
*/
auto add_child(std::unique_ptr<Unit>&& child_ptr) -> void;
auto add_child(core::UniqueObject&& child_ptr) -> void;

/**
* @brief Remove a child unit by index
Expand All @@ -130,7 +132,7 @@ namespace gkit::scene {
/**
* It is not use in the current version.
*/
// auto remove_child(std::unique_ptr<gkit::core::scene::Unit>& child_ptr) noexcept -> void;
// auto remove_child(core::UniqueObject& child_ptr) noexcept -> void;

/**
* @brief Get the number of children
Expand Down Expand Up @@ -188,28 +190,28 @@ namespace gkit::scene {

protected: // propertries
std::string name;
Unit* parent = nullptr;
core::ObjectId parent;

private: // children management
mutable std::mutex children_mutex{};
std::unordered_map<std::string, Unit*> name_map_cache{};
std::vector<std::unique_ptr<Unit>> children{};
std::unordered_map<std::string, core::ObjectId> name_map_cache{};
std::vector<core::UniqueObject> children{};

/**
* @brief Get child pointer by index.
* @brief Get child id by index.
* @param index The index of the child.
* @return Unit*
* If the index is valid, return the pointer to the child; otherwise return nullptr.
* @return core::ObjectId
* If the index is valid, return the id of the child; otherwise return invalid ObjectId.
*/
auto get_child(uint32_t index) noexcept -> Unit*;
auto get_child(uint32_t index) noexcept -> core::ObjectId;

/**
* @brief Get child pointer by name.
* @brief Get child id by name.
* @param child_name The name of the child.
* @return Unit*
* If the child exists in name cache, return the pointer; otherwise return nullptr.
* @return core::ObjectId
* If the child exists in name cache, return the id; otherwise return invalid ObjectId.
*/
auto get_child(const std::string& child_name) noexcept -> Unit*;
auto get_child(const std::string& child_name) noexcept -> core::ObjectId;

/**
* @brief Drop all children which are marked ready to drop.
Expand All @@ -226,19 +228,20 @@ namespace gkit::scene {
class UnitIterator {
public:
// NOLINTBEGIN(readability-identifier-naming)
using value_type = Unit;
using difference_type = std::ptrdiff_t;
using pointer = std::conditional_t<IsConst, const Unit*, Unit*>;
using reference = std::conditional_t<IsConst, const Unit&, Unit&>;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = Unit;
using difference_type = std::ptrdiff_t;
using pointer = std::conditional_t<IsConst, const core::ObjectId, core::ObjectId>;
using reference = std::conditional_t<IsConst, const core::ObjectId, core::ObjectId>;
// NOLINTEND(readability-identifier-naming)

private:
const Unit* m_owner;
const core::ObjectId m_owner;
size_t m_pos;

public:
UnitIterator() = default;
UnitIterator(const Unit* owner, size_t pos);
UnitIterator(const core::ObjectId owner, size_t pos);
auto operator*() const -> reference;
auto operator->() const -> pointer;
auto operator++() -> UnitIterator&;
Expand Down Expand Up @@ -278,7 +281,7 @@ namespace gkit::scene {

template<IsUnit UnitT, typename F, typename... Args>
auto Unit::with_child(uint32_t index, const F& func, Args&&... args) -> std::invoke_result_t<F, UnitT&, Args...> {
auto* child_ptr = get_child(index);
auto child_ptr = core::ObjectPool::instance().deref_from(get_child(index));
if (child_ptr == nullptr) {
throw std::out_of_range("Child index is out of range");
}
Expand All @@ -293,7 +296,7 @@ namespace gkit::scene {
template<IsUnit UnitT, typename F, typename... Args>
auto Unit::with_child(const std::string& child_name, const F& func, Args&&... args)
-> std::invoke_result_t<F, UnitT&, Args...> {
auto child_ptr = get_child(child_name);
auto child_ptr = core::ObjectPool::instance().deref_from(get_child(child_name));
if (child_ptr == nullptr) {
throw std::out_of_range("Child name is not found");
}
Expand All @@ -308,8 +311,8 @@ namespace gkit::scene {
template<IsUnit T>
auto Unit::get_parent() noexcept -> std::optional<std::reference_wrapper<T>> {
static_assert(std::is_base_of_v<Unit, T>, "T is not derived from Unit");
if (parent == nullptr) return std::nullopt;
auto cast_parent = dynamic_cast<T*>(parent);
if (parent == core::ObjectId{}) return std::nullopt;
auto cast_parent = dynamic_cast<T*>(core::ObjectPool::instance().deref_from(parent));
return cast_parent == nullptr ? std::nullopt : *cast_parent;
} // Unit::get_parent<T>
} // namespace gkit::scene
2 changes: 1 addition & 1 deletion src/core/object_pool.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "core/object_pool.hpp"
#include "gkit/core/object_pool.hpp"

#include "gkit/core/object.hpp"
#include "gkit/core/object_id.hpp"
Expand Down
14 changes: 8 additions & 6 deletions src/core/processer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_log.h>

gkit::Processer::Processer() noexcept : root() {
gkit::Processer::Processer() noexcept : root(gkit::core::UniqueObject::create<gkit::scene::Unit>()) {
SDL_InitFlags flags = SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO;

if (!SDL_Init(flags)) {
Expand All @@ -19,16 +19,18 @@ gkit::Processer::~Processer() noexcept {
SDL_Quit();
}

auto gkit::Processer::set_root(std::unique_ptr<scene::Unit>&& root_ptr) noexcept -> void {
if (root_ptr == nullptr) return;
this->root = std::move(root_ptr);
auto gkit::Processer::set_root(core::UniqueObject&& root_p) noexcept -> void {
auto root_ptr = root_p.get();
if (!root_ptr) return;
this->root = std::move(root_p);
}

auto gkit::Processer::run() -> void {
this->root->ready_handler();
auto root_ptr = dynamic_cast<scene::Unit*>(this->root.get());
root_ptr->ready_handler();
this->running.store(true);
while (this->running.load()) {
this->root->process_handler();
root_ptr->process_handler();
}
}

Expand Down
1 change: 0 additions & 1 deletion src/core/reflect/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "gkit/core/unique_object.hpp"

#include <optional>
#include <utility>

namespace gkit::core::reflect {

Expand Down
2 changes: 1 addition & 1 deletion src/core/reflect/seralize.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "core/reflect/seralize.hpp"

#include "core/object_pool.hpp"
#include "gkit/core/object_id.hpp"
#include "gkit/core/object_pool.hpp"
#include "gkit/core/reflect/registry.hpp"
#include "gkit/core/value.hpp"

Expand Down
21 changes: 14 additions & 7 deletions src/core/unique_object.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "gkit/core/unique_object.hpp"

#include "gkit/core/object_id.hpp"
#include "gkit/core/object_pool.hpp"
#include "gkit/core/reflect/registry.hpp"
#include "object_pool.hpp"

#include <string>
#include <utility>
Expand All @@ -12,24 +12,31 @@ namespace gkit::core {
return reflect::ClassDB::instance().create(class_name);
}

UniqueObject::UniqueObject(UniqueObject&& other) noexcept : id(std::move(other.id)) {
auto UniqueObject::get_id() const noexcept -> const ObjectId& {
static const ObjectId invalid_id{};
return this->obj == nullptr ? invalid_id : this->obj->get_object_id();
}

UniqueObject::UniqueObject(UniqueObject&& other) noexcept {
this->obj = other.obj;
other.obj = nullptr;
}

UniqueObject::~UniqueObject() noexcept {
if (this->obj == nullptr) return;
auto& obj_pool = ObjectPool::instance();
obj_pool.release(this->id);
obj_pool.release(this->obj->get_object_id());
}

auto UniqueObject::operator=(UniqueObject&& other) noexcept -> UniqueObject& {
if (this != &other) {
auto& obj_pool = ObjectPool::instance();
obj_pool.release(this->id);
this->id = std::move(other.id);
if (this->obj != nullptr) {
auto& obj_pool = ObjectPool::instance();
obj_pool.release(this->obj->get_object_id());
}
this->obj = other.obj;
other.obj = nullptr;
}
return *this;
}
} // namespace gkit::core
} // namespace gkit::core
Loading
Loading