bevy_mod_scripting_core/bindings/function/
namespace.rs1use crate::{
4 bindings::function::script_function::{AppScriptFunctionRegistry, ScriptFunction},
5 docgen::info::GetFunctionInfo,
6};
7use bevy::{
8 prelude::{AppTypeRegistry, World},
9 reflect::{GetTypeRegistration, Reflect},
10};
11use std::{any::TypeId, borrow::Cow, marker::PhantomData};
12
13use super::type_dependencies::GetFunctionTypeDependencies;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Reflect)]
16pub enum Namespace {
18 #[default]
21 Global,
22 OnType(TypeId),
25}
26
27pub struct GlobalNamespace;
29
30pub trait IntoNamespace {
32 fn into_namespace() -> Namespace;
34}
35
36impl<T: ?Sized + 'static> IntoNamespace for T {
37 fn into_namespace() -> Namespace {
38 if TypeId::of::<T>() == TypeId::of::<GlobalNamespace>() {
39 Namespace::Global
40 } else {
41 Namespace::OnType(TypeId::of::<T>())
42 }
43 }
44}
45
46impl Namespace {
48 pub fn prefix(self) -> Cow<'static, str> {
50 match self {
51 Namespace::Global => Cow::Borrowed(""),
52 Namespace::OnType(type_id) => Cow::Owned(format!("{:?}::", type_id)),
53 }
54 }
55
56 pub fn function_name<I: Into<Cow<'static, str>>>(self, name: I) -> Cow<'static, str> {
58 match self {
59 Namespace::Global => name.into(),
60 Namespace::OnType(type_id) => Cow::Owned(format!("{:?}::{}", type_id, name.into())),
61 }
62 }
63}
64
65pub struct NamespaceBuilder<'a, N> {
67 namespace: PhantomData<N>,
69 pub world: &'a mut World,
71}
72
73impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
74 pub fn new(world: &'a mut World) -> Self
77 where
78 S: GetTypeRegistration,
79 {
80 {
81 let registry = world.get_resource_or_init::<AppTypeRegistry>();
82 let mut registry = registry.write();
83 registry.register::<S>();
84 }
85 Self {
86 namespace: Default::default(),
87 world,
88 }
89 }
90
91 pub fn new_unregistered(world: &'a mut World) -> Self {
93 Self {
94 namespace: Default::default(),
95 world,
96 }
97 }
98
99 pub fn register<'env, N, F, M>(&mut self, name: N, function: F) -> &mut Self
101 where
102 N: Into<Cow<'static, str>>,
103 F: ScriptFunction<'env, M> + GetFunctionTypeDependencies<M> + GetFunctionInfo<M>,
104 {
105 self.register_inner(name, function, None, None)
106 }
107
108 pub fn register_documented<'env, N, F, M>(
110 &mut self,
111 name: N,
112 function: F,
113 docstring: &'static str,
114 arg_names: &'static [&'static str],
115 ) -> &mut Self
116 where
117 N: Into<Cow<'static, str>>,
118 F: ScriptFunction<'env, M> + GetFunctionTypeDependencies<M> + GetFunctionInfo<M>,
119 {
120 self.register_inner(name, function, Some(docstring), Some(arg_names))
121 }
122
123 fn register_inner<'env, N, F, M>(
124 &mut self,
125 name: N,
126 function: F,
127 docstring: Option<&'static str>,
128 arg_names: Option<&'static [&'static str]>,
129 ) -> &mut Self
130 where
131 N: Into<Cow<'static, str>>,
132 F: ScriptFunction<'env, M> + GetFunctionTypeDependencies<M> + GetFunctionInfo<M>,
133 {
134 {
135 {
136 let mut registry = self
137 .world
138 .get_resource_or_init::<AppScriptFunctionRegistry>();
139 let mut registry = registry.write();
140 registry.register_with_arg_names(
141 S::into_namespace(),
142 name,
143 function,
144 docstring.unwrap_or_default(),
145 arg_names.unwrap_or(&[]),
146 );
147 }
148 {
149 let type_registry = self.world.get_resource_or_init::<AppTypeRegistry>();
150 let mut type_registry = type_registry.write();
151 F::register_type_dependencies(&mut type_registry);
152 }
153 }
154 self
155 }
156}