Skip to content

Commit f579a84

Browse files
authored
Restructure modules (#50)
Closes #48
1 parent 501596c commit f579a84

18 files changed

+769
-768
lines changed

derive/src/impl_attribute.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn godot_script_impl(
6969
(
7070
quote_spanned! {
7171
arg.span() =>
72-
::godot_rust_script::RustScriptPropDesc {
72+
::godot_rust_script::private_export::RustScriptPropDesc {
7373
name: stringify!(#arg_name),
7474
ty: #arg_type,
7575
exported: false,
@@ -126,10 +126,10 @@ pub fn godot_script_impl(
126126

127127
let metadata = quote_spanned! {
128128
fnc.span() =>
129-
::godot_rust_script::RustScriptMethodDesc {
129+
::godot_rust_script::private_export::RustScriptMethodDesc {
130130
name: #fn_name_str,
131131
arguments: Box::new([#args_meta]),
132-
return_type: ::godot_rust_script::RustScriptPropDesc {
132+
return_type: ::godot_rust_script::private_export::RustScriptPropDesc {
133133
name: #fn_name_str,
134134
ty: #fn_return_ty,
135135
exported: false,

derive/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
7272

7373
let description = get_field_description(field);
7474
let item = quote! {
75-
::godot_rust_script::RustScriptPropDesc {
75+
::godot_rust_script::private_export::RustScriptPropDesc {
7676
name: #name,
7777
ty: #ty,
7878
exported: #exported,
@@ -97,7 +97,7 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
9797
let signal_type = &field.ty;
9898

9999
quote! {
100-
::godot_rust_script::RustScriptSignalDesc {
100+
::godot_rust_script::private_export::RustScriptSignalDesc {
101101
name: #signal_name,
102102
arguments: <#signal_type as ::godot_rust_script::ScriptSignal>::argument_desc(),
103103
description: concat!(#signal_description),

license_header.nu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ def main []: nothing -> nothing {
2727
continue
2828
}
2929

30-
read_file $file | prepend $license_notice | str join "\n" | save -f $file.name
30+
read_file $file | prepend $license_notice | str join "\n" | collect | save -f $file
3131
}
3232
}

rust-script/src/interface.rs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
5+
*/
6+
7+
mod signals;
8+
9+
use std::marker::PhantomData;
10+
use std::ops::{Deref, DerefMut};
11+
use std::{collections::HashMap, fmt::Debug};
12+
13+
use godot::obj::Inherits;
14+
use godot::prelude::{Gd, Object, StringName, Variant};
15+
16+
pub use crate::runtime::Context;
17+
18+
pub use signals::{ScriptSignal, Signal};
19+
20+
pub trait GodotScript: Debug + GodotScriptImpl<ImplBase = Self::Base> {
21+
type Base: Inherits<Object>;
22+
23+
const CLASS_NAME: &'static str;
24+
25+
fn set(&mut self, name: StringName, value: Variant) -> bool;
26+
fn get(&self, name: StringName) -> Option<Variant>;
27+
fn call(
28+
&mut self,
29+
method: StringName,
30+
args: &[&Variant],
31+
context: Context<'_, Self>,
32+
) -> Result<Variant, godot::sys::GDExtensionCallErrorType>;
33+
34+
fn to_string(&self) -> String;
35+
fn property_state(&self) -> HashMap<StringName, Variant>;
36+
37+
fn default_with_base(base: godot::prelude::Gd<godot::prelude::Object>) -> Self;
38+
}
39+
40+
pub trait GodotScriptImpl {
41+
type ImplBase: Inherits<Object>;
42+
43+
fn call_fn(
44+
&mut self,
45+
name: StringName,
46+
args: &[&Variant],
47+
context: Context<Self>,
48+
) -> Result<Variant, godot::sys::GDExtensionCallErrorType>;
49+
}
50+
51+
#[derive(Debug)]
52+
pub struct RsRef<T: GodotScript> {
53+
owner: Gd<T::Base>,
54+
script_ty: PhantomData<T>,
55+
}
56+
57+
impl<T: GodotScript> RsRef<T> {
58+
pub(crate) fn new<B: Inherits<T::Base> + Inherits<Object>>(owner: Gd<B>) -> Self {
59+
Self {
60+
owner: owner.upcast(),
61+
script_ty: PhantomData,
62+
}
63+
}
64+
65+
fn validate_script<O: Inherits<Object>>(owner: &Gd<O>) -> Option<GodotScriptCastError> {
66+
let script = owner
67+
.upcast_ref::<Object>()
68+
.get_script()
69+
.try_to::<Option<Gd<crate::runtime::RustScript>>>();
70+
71+
let Ok(script) = script else {
72+
return Some(GodotScriptCastError::NotRustScript);
73+
};
74+
75+
let Some(script) = script else {
76+
return Some(GodotScriptCastError::NoScriptAttached);
77+
};
78+
79+
let class_name = script.bind().str_class_name();
80+
81+
(class_name != T::CLASS_NAME).then(|| {
82+
GodotScriptCastError::ClassMismatch(T::CLASS_NAME, script.get_class().to_string())
83+
})
84+
}
85+
}
86+
87+
impl<T: GodotScript> Deref for RsRef<T> {
88+
type Target = Gd<T::Base>;
89+
90+
fn deref(&self) -> &Self::Target {
91+
&self.owner
92+
}
93+
}
94+
95+
impl<T: GodotScript> DerefMut for RsRef<T> {
96+
fn deref_mut(&mut self) -> &mut Self::Target {
97+
&mut self.owner
98+
}
99+
}
100+
101+
impl<T: GodotScript> Clone for RsRef<T> {
102+
fn clone(&self) -> Self {
103+
Self {
104+
owner: self.owner.clone(),
105+
script_ty: PhantomData,
106+
}
107+
}
108+
}
109+
110+
#[derive(thiserror::Error, Debug)]
111+
pub enum GodotScriptCastError {
112+
#[error("Object has no script attached!")]
113+
NoScriptAttached,
114+
115+
#[error("Script attached to object is not a RustScript!")]
116+
NotRustScript,
117+
118+
#[error(
119+
"Script attached to object does not match expected script class `{0}` but found `{1}`!"
120+
)]
121+
ClassMismatch(&'static str, String),
122+
}
123+
124+
pub trait CastToScript<T: GodotScript> {
125+
fn try_to_script(&self) -> Result<RsRef<T>, GodotScriptCastError>;
126+
fn try_into_script(self) -> Result<RsRef<T>, GodotScriptCastError>;
127+
fn to_script(&self) -> RsRef<T>;
128+
fn into_script(self) -> RsRef<T>;
129+
}
130+
131+
impl<T: GodotScript, B: Inherits<T::Base> + Inherits<Object>> CastToScript<T> for Gd<B> {
132+
fn try_to_script(&self) -> Result<RsRef<T>, GodotScriptCastError> {
133+
if let Some(err) = RsRef::<T>::validate_script(self) {
134+
return Err(err);
135+
}
136+
137+
Ok(RsRef::new(self.clone()))
138+
}
139+
140+
fn try_into_script(self) -> Result<RsRef<T>, GodotScriptCastError> {
141+
if let Some(err) = RsRef::<T>::validate_script(&self) {
142+
return Err(err);
143+
}
144+
145+
Ok(RsRef::new(self))
146+
}
147+
148+
fn to_script(&self) -> RsRef<T> {
149+
self.try_to_script().unwrap_or_else(|err| {
150+
panic!(
151+
"`{}` was assumed to have rust script `{}`, but this was not the case at runtime!\nError: {}",
152+
B::class_name(),
153+
T::CLASS_NAME,
154+
err,
155+
);
156+
})
157+
}
158+
159+
fn into_script(self) -> RsRef<T> {
160+
self.try_into_script().unwrap_or_else(|err| {
161+
panic!(
162+
"`{}` was assumed to have rust script `{}`, but this was not the case at runtime!\nError: {}",
163+
B::class_name(),
164+
T::CLASS_NAME,
165+
err
166+
);
167+
})
168+
}
169+
}
170+
171+
#[macro_export]
172+
macro_rules! setup_library {
173+
() => {
174+
#[no_mangle]
175+
pub fn __godot_rust_script_init(
176+
) -> ::std::vec::Vec<$crate::private_export::RustScriptMetaData> {
177+
use $crate::godot::obj::EngineEnum;
178+
use $crate::private_export::*;
179+
180+
let lock = $crate::private_export::__godot_rust_plugin_SCRIPT_REGISTRY
181+
.lock()
182+
.expect("unable to aquire mutex lock");
183+
184+
$crate::private_export::assemble_metadata(lock.iter())
185+
}
186+
187+
pub const __GODOT_RUST_SCRIPT_SRC_ROOT: &str = $crate::private_export::concat!(
188+
env!("CARGO_MANIFEST_DIR"),
189+
"/src",
190+
$crate::private_export::replace!(
191+
$crate::private_export::unwrap!($crate::private_export::strip_prefix!(
192+
module_path!(),
193+
$crate::private_export::replace!(env!("CARGO_PKG_NAME"), "-", "_")
194+
)),
195+
"::",
196+
"/"
197+
),
198+
);
199+
};
200+
}
201+
202+
#[macro_export]
203+
macro_rules! init {
204+
($scripts_module:tt) => {
205+
$crate::RustScriptExtensionLayer::initialize(
206+
$scripts_module::__godot_rust_script_init,
207+
$scripts_module::__GODOT_RUST_SCRIPT_SRC_ROOT,
208+
)
209+
};
210+
}
211+
212+
#[macro_export]
213+
macro_rules! deinit {
214+
() => {
215+
$crate::RustScriptExtensionLayer::deinitialize()
216+
};
217+
}

rust-script/src/library/signals.rs renamed to rust-script/src/interface/signals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use godot::global::{Error, PropertyHint};
1414
use godot::meta::{GodotConvert, GodotType, ToGodot};
1515
use godot::obj::Gd;
1616

17-
use super::RustScriptPropDesc;
17+
use crate::static_script_registry::RustScriptPropDesc;
1818

1919
pub trait ScriptSignal {
2020
type Args: SignalArguments;

rust-script/src/lib.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,22 @@
55
*/
66

77
mod apply;
8-
mod script_registry;
9-
mod shared;
108

11-
#[cfg(feature = "scripts")]
12-
mod library;
13-
#[cfg(feature = "runtime")]
9+
mod interface;
1410
mod runtime;
11+
mod static_script_registry;
1512

16-
#[cfg(feature = "scripts")]
17-
pub use library::*;
18-
#[cfg(feature = "runtime")]
19-
pub use runtime::*;
20-
21-
#[cfg(feature = "scripts")]
2213
pub use godot_rust_script_derive::{godot_script_impl, GodotScript};
14+
pub use interface::*;
15+
pub use runtime::RustScriptExtensionLayer;
2316

17+
#[doc(hidden)]
2418
pub mod private_export {
25-
pub use super::shared::__godot_rust_plugin_SCRIPT_REGISTRY;
19+
pub use crate::static_script_registry::{
20+
RustScriptMetaData, __godot_rust_plugin_SCRIPT_REGISTRY, assemble_metadata,
21+
create_default_data_struct, RegistryItem, RustScriptEntry, RustScriptEntryMethods,
22+
RustScriptMethodDesc, RustScriptPropDesc, RustScriptSignalDesc,
23+
};
2624
pub use const_str::{concat, replace, strip_prefix, unwrap};
2725
pub use godot::sys::{plugin_add, plugin_registry};
2826
}

0 commit comments

Comments
 (0)