Skip to content

Commit 1fec623

Browse files
committed
docs changes
1 parent 36c426d commit 1fec623

File tree

8 files changed

+122
-15
lines changed

8 files changed

+122
-15
lines changed

crates/bevy_mod_scripting_bindings/src/function/namespace.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! A module for managing namespaces for functions
22
33
use crate::{
4+
DummyScriptFunctionRegistry, ScriptFunctionRegistryArc,
45
docgen::info::GetFunctionInfo,
56
function::script_function::{AppScriptFunctionRegistry, ScriptFunction},
67
};
@@ -66,6 +67,8 @@ impl Namespace {
6667

6768
/// A convenience builder for registering multiple functions in a namespace
6869
pub struct NamespaceBuilder<'a, N> {
70+
/// If true will use the dummy function registry instead
71+
registry: ScriptFunctionRegistryArc,
6972
/// phantom data to reference the namespace type
7073
namespace: PhantomData<N>,
7174
/// a cached reference to the world
@@ -86,6 +89,10 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
8689
registry.register::<S>();
8790
}
8891
Self {
92+
registry: world
93+
.get_resource_or_init::<AppScriptFunctionRegistry>()
94+
.0
95+
.clone(),
8996
namespace: Default::default(),
9097
world,
9198
}
@@ -94,11 +101,27 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
94101
/// Prefer using the `register` method on the `NamespaceBuilder` instead
95102
pub fn new_unregistered(world: &'a mut World) -> Self {
96103
Self {
104+
registry: world
105+
.get_resource_or_init::<AppScriptFunctionRegistry>()
106+
.0
107+
.clone(),
97108
namespace: Default::default(),
98109
world,
99110
}
100111
}
101112

113+
/// Register functions for this namespace on the dummy function registry instead.
114+
///
115+
/// This will appear in documentation but not become callable.
116+
pub fn with_dummy_registry(mut self) -> Self {
117+
self.registry = self
118+
.world
119+
.get_resource_or_init::<DummyScriptFunctionRegistry>()
120+
.0
121+
.clone();
122+
self
123+
}
124+
102125
/// Registers a function in the namespace
103126
pub fn register<'env, N, F, M>(&mut self, name: N, function: F) -> &mut Self
104127
where
@@ -136,10 +159,7 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
136159
{
137160
{
138161
{
139-
let mut registry = self
140-
.world
141-
.get_resource_or_init::<AppScriptFunctionRegistry>();
142-
let mut registry = registry.write();
162+
let mut registry = self.registry.write();
143163
registry.register_with_arg_names(
144164
S::into_namespace(),
145165
name,

crates/bevy_mod_scripting_bindings/src/function/script_function.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,16 @@ where
258258
}
259259
}
260260

261+
/// Identical to the [`AppScriptFunctionRegistry`], but the functions only exist for docs purposes, use if you provide functions at a lower level,
262+
/// but still want to include the function in the docs
263+
#[derive(Clone, Default, Resource, DebugWithTypeInfo)]
264+
#[debug_with_type_info(bms_display_path = "bevy_mod_scripting_display")]
265+
pub struct DummyScriptFunctionRegistry(pub ScriptFunctionRegistryArc);
266+
261267
/// Equivalent to [`AppFunctionRegistry`] but stores functions with a more convenient signature for scripting to avoid boxing every argument.
262268
#[derive(Clone, Default, Resource, DebugWithTypeInfo)]
263269
#[debug_with_type_info(bms_display_path = "bevy_mod_scripting_display")]
264-
pub struct AppScriptFunctionRegistry(ScriptFunctionRegistryArc);
270+
pub struct AppScriptFunctionRegistry(pub ScriptFunctionRegistryArc);
265271

266272
impl Deref for AppScriptFunctionRegistry {
267273
type Target = ScriptFunctionRegistryArc;

crates/bevy_mod_scripting_core/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use bevy_mod_scripting_asset::{Language, LanguageExtensions, ScriptAsset, Script
2222

2323
use bevy_mod_scripting_bindings::{
2424
AppReflectAllocator, AppScheduleRegistry, AppScriptFunctionRegistry,
25-
DynamicScriptComponentPlugin, MarkAsCore, ReflectReference, ScriptTypeRegistration,
26-
ScriptValue, ThreadWorldContainer, garbage_collector,
25+
DummyScriptFunctionRegistry, DynamicScriptComponentPlugin, MarkAsCore, ReflectReference,
26+
ScriptTypeRegistration, ScriptValue, ThreadWorldContainer, garbage_collector,
2727
};
2828
use context::{Context, ContextInitializer, ContextPreHandlingInitializer};
2929
use event::{ScriptCallbackEvent, ScriptCallbackResponseEvent};
@@ -343,6 +343,7 @@ impl Plugin for BMSScriptingInfrastructurePlugin {
343343
.init_resource::<AppReflectAllocator>()
344344
.init_asset::<ScriptAsset>()
345345
.init_resource::<AppScriptFunctionRegistry>()
346+
.init_resource::<DummyScriptFunctionRegistry>()
346347
.insert_resource(AppScheduleRegistry::new());
347348

348349
app.register_type::<ScriptAsset>();

crates/bevy_mod_scripting_derive/src/derive/script_bindings.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,18 @@ pub fn script_bindings(
8282
Default::default()
8383
};
8484

85+
let use_dummy = if args.use_dummy_registry {
86+
quote_spanned! {impl_span=>
87+
.with_dummy_registry()
88+
}
89+
} else {
90+
Default::default()
91+
};
92+
8593
let out = quote_spanned! {impl_span=>
8694
#visibility fn #function_name(world: &mut World) {
8795
#bms_bindings_path::function::namespace::NamespaceBuilder::<#type_ident_with_generics>::#builder_function_name(world)
96+
#use_dummy
8897
#(#function_registrations)*;
8998

9099
#mark_as_generated
@@ -113,6 +122,9 @@ struct Args {
113122
pub core: bool,
114123
/// If true registers a marker type against the type registry to state that the type is significant (if unregistered is not set)
115124
pub significant: bool,
125+
/// If true will register into the [`DummyScriptFunctionRegistry`] instead of the full one.
126+
/// This is useful for documenting functions without actually making them available, if you're exposing them another way.
127+
pub use_dummy_registry: bool,
116128
}
117129

118130
impl syn::parse::Parse for Args {
@@ -127,6 +139,7 @@ impl syn::parse::Parse for Args {
127139
let mut generated = false;
128140
let mut core = false;
129141
let mut significant = false;
142+
let mut use_dummy_registry = false;
130143
let mut bms_bindings_path =
131144
syn::Path::from(syn::Ident::new("bevy_mod_scripting", Span::call_site()));
132145
bms_bindings_path.segments.push(syn::PathSegment {
@@ -152,6 +165,9 @@ impl syn::parse::Parse for Args {
152165
} else if path.is_ident("significant") {
153166
significant = true;
154167
continue;
168+
} else if path.is_ident("use_dummy_registry") {
169+
use_dummy_registry = true;
170+
continue;
155171
}
156172
}
157173
syn::Meta::NameValue(name_value) => {
@@ -190,6 +206,7 @@ impl syn::parse::Parse for Args {
190206
generated,
191207
core,
192208
significant,
209+
use_dummy_registry,
193210
})
194211
}
195212
}

crates/bevy_mod_scripting_derive/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn into_script(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
2727
/// - `unregistered`: If set, will use `new_unregistered` instead of `new` for the namespace builder
2828
/// - `core`: If set, marks the type as `core` using the `MarkAsCore` type data
2929
/// - `significant`: If set, marks the type as `significant` using the `MarkAsSignificant` type data
30+
/// - `use_dummy_registry`: If true will register into the [`DummyScriptFunctionRegistry`] instead of the full one. This is useful for documenting functions without actually making them available, if you're exposing them another way.
3031
///
3132
/// It is encouraged to place `significant` markers on your own types, for the purposes of documentation generation.
3233
#[proc_macro_attribute]

crates/bevy_mod_scripting_functions/src/core.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use bevy_app::App;
99
use bevy_asset::{AssetServer, Handle};
1010
use bevy_ecs::{entity::Entity, prelude::AppTypeRegistry, schedule::Schedules, world::World};
1111
use bevy_mod_scripting_bindings::{
12-
DynamicScriptFunctionMut, FunctionInfo, GlobalNamespace, InteropError, PartialReflectExt,
13-
ReflectReference, ScriptComponentRegistration, ScriptQueryBuilder, ScriptQueryResult,
14-
ScriptResourceRegistration, ScriptTypeRegistration, ThreadWorldContainer, Union,
12+
DynamicScriptFunction, DynamicScriptFunctionMut, FunctionInfo, GlobalNamespace, InteropError,
13+
PartialReflectExt, ReflectReference, ScriptComponentRegistration, ScriptQueryBuilder,
14+
ScriptQueryResult, ScriptResourceRegistration, ScriptTypeRegistration, ThreadWorldContainer,
15+
Union,
1516
function::{
1617
from::{Ref, Val},
1718
from_ref::FromScriptRef,
@@ -1329,6 +1330,48 @@ impl Handle<ScriptAsset> {
13291330
}
13301331
}
13311332

1333+
/// globals which are being registered at lower level within each language plugin.
1334+
#[script_bindings(
1335+
remote,
1336+
bms_bindings_path = "bevy_mod_scripting_bindings",
1337+
name = "global_namespace_dummy_functions",
1338+
unregistered,
1339+
use_dummy_registry
1340+
)]
1341+
impl GlobalNamespace {
1342+
/// Registers a "frozen" callback handler,
1343+
///
1344+
/// For example, this code:
1345+
///
1346+
/// ```lua
1347+
/// register_callback("on_script_unloaded", my_unload_handler)
1348+
///
1349+
/// function my_unload_handler()
1350+
/// print("handling unload!")
1351+
/// end
1352+
/// ```
1353+
///
1354+
/// would call the `my_unload_handler` function, whenever the `on_script_unloaded` callback is triggered, which is when your script is about to be unloaded.
1355+
///
1356+
/// Registered callbacks take precedence over free-standing function callbacks, i.e. the below top level function:
1357+
/// ```lua
1358+
/// function on_script_unloaded()
1359+
/// print("freestanding unload handler!")
1360+
/// end
1361+
/// ```
1362+
///
1363+
/// would be a valid handler, but if a registered callback existed, it would be called instead.
1364+
///
1365+
/// Arguments:
1366+
/// * `callback`: the callback label to register this function against.
1367+
/// * `function`: the callback function which will be stored as a handler for this callback label.
1368+
fn register_callback(callback: String, function: DynamicScriptFunction) {
1369+
// to avoid clippy unused errors.
1370+
println!("dummy called!: {callback:?}, {function:?}");
1371+
}
1372+
}
1373+
1374+
/// Globals registered by us
13321375
#[script_bindings(
13331376
remote,
13341377
bms_bindings_path = "bevy_mod_scripting_bindings",
@@ -1421,5 +1464,6 @@ pub fn register_core_functions(app: &mut App) {
14211464
register_script_handle_functions(world);
14221465

14231466
register_global_namespace_functions(world);
1467+
register_global_namespace_dummy_functions(world);
14241468
}
14251469
}

crates/ladfile_builder/src/plugin.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ::{
88
};
99
use bevy_log::{error, info};
1010
use bevy_mod_scripting_bindings::{
11-
IntoNamespace,
11+
DummyScriptFunctionRegistry, IntoNamespace,
1212
function::{namespace::Namespace, script_function::AppScriptFunctionRegistry},
1313
globals::AppScriptGlobalsRegistry,
1414
};
@@ -74,11 +74,13 @@ impl ScriptingDocgenPlugin {
7474
pub fn generate_lad_file(
7575
type_registry: &AppTypeRegistry,
7676
function_registry: &AppScriptFunctionRegistry,
77+
dummy_function_registry: &DummyScriptFunctionRegistry,
7778
global_registry: &AppScriptGlobalsRegistry,
7879
settings: &LadFileSettings,
7980
) {
8081
let type_registry = type_registry.read();
8182
let function_registry = function_registry.read();
83+
let dummy_function_registry = dummy_function_registry.0.read();
8284
let global_registry = global_registry.read();
8385
let mut builder = LadFileBuilder::new(&type_registry);
8486
builder
@@ -92,7 +94,10 @@ pub fn generate_lad_file(
9294
r#"The ECS world containing all Components, Resources and Systems. Main point of interaction with a Bevy App."#.trim(),
9395
);
9496

95-
for (_, function) in function_registry.iter_namespace(World::into_namespace()) {
97+
for (_, function) in function_registry
98+
.iter_namespace(World::into_namespace())
99+
.chain(dummy_function_registry.iter_namespace(World::into_namespace()))
100+
{
96101
builder.add_function_info(&function.info);
97102
}
98103

@@ -113,15 +118,19 @@ pub fn generate_lad_file(
113118
builder.add_type_info(type_info);
114119

115120
// find functions on the namespace
116-
for (_, function) in
117-
function_registry.iter_namespace(Namespace::OnType(type_info.type_id()))
121+
for (_, function) in function_registry
122+
.iter_namespace(Namespace::OnType(type_info.type_id()))
123+
.chain(dummy_function_registry.iter_namespace(Namespace::OnType(type_info.type_id())))
118124
{
119125
builder.add_function_info(&function.info);
120126
}
121127
}
122128

123129
// find functions on the global namespace
124-
for (_, function) in function_registry.iter_namespace(Namespace::Global) {
130+
for (_, function) in function_registry
131+
.iter_namespace(Namespace::Global)
132+
.chain(dummy_function_registry.iter_namespace(Namespace::Global))
133+
{
125134
builder.add_function_info(&function.info);
126135
}
127136

@@ -171,12 +180,14 @@ pub fn generate_lad_file(
171180
fn generate_lad_file_system(
172181
type_registry: Res<AppTypeRegistry>,
173182
function_registry: Res<AppScriptFunctionRegistry>,
183+
dummy_function_registry: Res<DummyScriptFunctionRegistry>,
174184
global_registry: Res<AppScriptGlobalsRegistry>,
175185
settings: Res<LadFileSettings>,
176186
) {
177187
generate_lad_file(
178188
&type_registry,
179189
&function_registry,
190+
&dummy_function_registry,
180191
&global_registry,
181192
&settings,
182193
);

examples/docgen.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use bevy::{DefaultPlugins, app::App, ecs::reflect::AppTypeRegistry};
22
use bevy_mod_scripting::ScriptFunctionsPlugin;
33
use bevy_mod_scripting_bindings::{
4+
DummyScriptFunctionRegistry,
45
function::script_function::AppScriptFunctionRegistry,
56
globals::{AppScriptGlobalsRegistry, core::CoreScriptGlobalsPlugin},
67
};
@@ -44,6 +45,11 @@ fn main() -> std::io::Result<()> {
4445
.get_resource::<AppScriptFunctionRegistry>()
4546
.unwrap()
4647
.clone();
48+
let dummy_function_registry = app
49+
.world()
50+
.get_resource::<DummyScriptFunctionRegistry>()
51+
.unwrap()
52+
.clone();
4753
let global_registry = app
4854
.world()
4955
.get_resource::<AppScriptGlobalsRegistry>()
@@ -58,6 +64,7 @@ fn main() -> std::io::Result<()> {
5864
generate_lad_file(
5965
&type_registry,
6066
&function_registry,
67+
&dummy_function_registry,
6168
&global_registry,
6269
&settings,
6370
);

0 commit comments

Comments
 (0)