81class [[ToastNode, Icon(
"Circle")]] TOAST_API Node {
82 friend class INodeOwner;
84 friend class Workspace;
85 friend class PlayWorkspace;
86 friend class TickScheduler;
100 auto uid()
const noexcept ->
const UID&;
104 auto rid()
const noexcept -> std::uintptr_t;
108 auto name()
const noexcept -> std::string_view;
114 void name(std::string_view
name)
noexcept;
122 auto enabled()
const noexcept -> bool;
125 auto participatesIn(NodeOwnerParticipation use)
const noexcept ->
bool {
126 return m_owner !=
nullptr && m_owner->participatesIn(use);
136 auto owner() const noexcept -> INodeOwner* {
144 void enabled(
bool value)
noexcept;
151 auto box() const noexcept ->
Box<
Node>;
160 auto info() const -> const
NodeInfo*;
167 auto sourcePrefab() const noexcept -> const assets::Handle<assets::Prefab>&;
175 auto isInstanceRoot() const noexcept ->
bool;
182 auto root() const noexcept ->
Box<
Node>;
198 auto listener() noexcept -> event::Listener&;
205 auto parent() noexcept ->
Box<
Node>;
219 auto childrenSnapshot() const -> std::vector<
Box<
Node>>;
229 return m_owner->requestRuntimeCreate(*
this,
type);
233 TOAST_NOT_IMPLEMENTED;
245 return m_owner->requestRuntimeSpawn(*
this,
uid);
249 TOAST_NOT_IMPLEMENTED;
261 return m_owner->requestRuntimeSpawn(*
this, uri);
265 TOAST_NOT_IMPLEMENTED;
278 auto find(std::string_view query) ->
Box<Node>;
297 auto search(std::string_view query) -> std::vector<Box<Node>>;
300 auto childrenOfType(
const NodeInfo* type)
const -> std::vector<Box<Node>>;
303 auto searchType(
const NodeInfo* type)
const -> std::vector<Box<Node>>;
305 void addDependsOn(
Node& other);
306 void removeDependsOn(
Node& other);
311 void interactsWith(
Node& other);
314 auto scriptRuntime() noexcept -> scripting::ScriptRuntime* {
315 return m_script_runtime.get();
322 auto hasTickFunction(TickFunctionList mask)
const noexcept -> bool;
333 auto scriptVm(TickFunctionList func)
const noexcept -> std::optional<size_t>;
337 auto scriptVmAny() const noexcept -> std::optional<
size_t>;
341 auto hasCallable(std::string_view name) const noexcept ->
bool;
346 void reloadScripts() noexcept;
350 auto
scripts() const noexcept -> const std::vector<assets::Handle<assets::Script>>& {
356 m_scripts = std::move(
scripts);
363 m_scripts.push_back(script);
372 template<
typename R = void,
typename... Args>
373 auto call(std::string_view
name, Args&&... args) -> R {
374 std::array<std::any,
sizeof...(Args)> any_args {std::any(std::decay_t<Args>(args))...};
375 if constexpr (std::is_void_v<R>) {
376 if (m_info && m_info->getMethod(
name)) {
377 _detail::callMethodChain(m_info,
this,
name, args...);
379 _detail::callNodeScripts(
this,
name, any_args);
382 if (m_info && m_info->getMethod(
name)) {
383 result = _detail::callMethodChain<R>(m_info,
this,
name, args...);
385 _detail::callNodeScripts(
this,
name, any_args);
399 if (
const auto* f = m_info->getField(
name)) {
400 std::any v = f->get(
const_cast<Node*
>(
this));
401 if (
auto* p = std::any_cast<T>(&v)) {
406 std::any v = _detail::getNodeScriptVar(
this,
name);
407 if (
auto* p = std::any_cast<T>(&v)) {
418 void set(std::string_view
name,
const T& value) {
420 if (
const auto* f = m_info->getField(
name)) {
421 f->set(
this, std::any(value));
422 onReflectedFieldChanged(f->name);
425 _detail::setNodeScriptVar(
this,
name, std::any(value));
428 signals::Signal<Box<Node>> on_enable;
429 signals::Signal<Box<Node>> on_disable;
430 signals::Signal<Box<Node>> on_begin;
431 signals::Signal<Box<Node>> on_end;
436 virtual void onReflectedFieldChanged(std::string_view ) { }
438 virtual void onScriptsReloaded() { }
444 virtual auto luaAffinity() const noexcept -> std::optional<
size_t> {
451 virtual void updateInspectorMessages() { }
453 void addInspectorMessage(
const NodeMessage& message) {
454 for (
auto& existing : m_messages) {
455 if (existing == message) {
460 m_messages.emplace_back(message);
463 void removeInspectorMessage(
const NodeMessage& message) { m_messages.remove(message); }
466 bool m_recursive_prefab =
false;
470 auto isRecursivePrefab() const noexcept ->
bool {
471 return m_recursive_prefab;
480 bool m_local_enabled =
false;
481 bool m_inherited_enabled =
false;
483 [[Reflect, Name(
"Parent"), InspectorNoModify]]
486 [[Reflect, Name(
"Prefab"), InspectorNoModify]]
487 assets::Handle<assets::Prefab> m_source_prefab;
491 std::array<uint8_t, 5> m_wave = {
492 255, 255, 255, 255, 255
496 const NodeInfo* m_info =
nullptr;
497 std::string m_reflect_type_name;
498 bool m_prefab_interior =
500 std::vector<Box<Node>> m_children;
501 std::shared_ptr<const assets::Prefab::BasicNode>
504 std::unique_ptr<event::Listener> m_listener =
nullptr;
507 std::vector<assets::Handle<assets::Script>> m_scripts;
510 std::unique_ptr<scripting::ScriptRuntime> m_script_runtime;
512 uint64_t m_script_group = 0;
513 std::optional<size_t> m_script_vm;
515 enum LifecycleBits : uint8_t {
516 lifecycle_loaded = 1 << 0,
517 lifecycle_initialized = 1 << 1,
518 lifecycle_begun = 1 << 2,
519 lifecycle_enabled = 1 << 3,
522 uint8_t m_lifecycle = 0;
525 auto parentInternal() const noexcept -> Box<Node> {
530 auto rootUnlocked() const noexcept -> Box<Node>;
532 void inheritedEnabled(
bool value) noexcept;
533 void changeNodeState(NodeState state) noexcept;
536 void callTick(const NodeInfo* info, TickFunctionList func_type) noexcept;
539 void callTickNative(const NodeInfo* info, TickFunctionList func_type) noexcept;
541 void callTickScripts(TickFunctionList func_type) noexcept;
544 void propagateCallTick(const NodeInfo* info, TickFunctionList func_type) noexcept;
547 void propagateEnable() noexcept;
553 void loadScripts() noexcept;
555 std::list<NodeMessage> m_messages;