Skip to content

Commit

Permalink
fully seperating scripts lib and runtime (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
TitanNano authored Nov 5, 2023
1 parent 669e103 commit 54fbe15
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 113 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ edition = "2021"
crate-type = ["cdylib"]

[dependencies]
godot-rust-script = { git = "https://github.com/TitanNano/godot-rust-script.git", branch = "master" }
godot-rust-script = { git = "https://github.com/TitanNano/godot-rust-script.git", branch = "master", features = ["runtime"] }
scripts = { path = "./scripts" }
```

Expand Down Expand Up @@ -88,7 +88,7 @@ edition = "2021"
crate-type = ["dylib", "rlib"]

[dependencies]
godot-rust-script = { git = "https://github.com/TitanNano/godot-rust-script.git", branch = "master" }
godot-rust-script = { git = "https://github.com/TitanNano/godot-rust-script.git", branch = "master", features = ["scripts"] }
```

scripts-lib/src/lib.rs
Expand Down
11 changes: 7 additions & 4 deletions rust-script/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ edition.workspace = true

[dependencies]
godot.workspace = true
itertools.workspace = true
abi_stable.workspace = true
rand.workspace = true
cfg-if.workspace = true

hot-lib-reloader = { workspace = true, optional = true }
itertools = { workspace = true, optional = true }
rand = { workspace = true, optional = true }
process_path = { workspace = true, optional = true }

godot-rust-script-derive.workspace = true
godot-rust-script-derive = { workspace = true, optional = true }

[dev-dependencies]
tests-scripts-lib = { path = "../tests-scripts-lib", features = ["hot-reload"] }
godot-rust-script = { path = "./", features = ["runtime"] }

[features]
default = ["hot-reload"]
hot-reload = ["dep:process_path", "dep:hot-lib-reloader"]
hot-reload = ["dep:process_path", "dep:hot-lib-reloader"]
runtime = ["dep:itertools", "dep:rand"]
scripts = ["dep:godot-rust-script-derive"]
11 changes: 9 additions & 2 deletions rust-script/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
mod apply;
mod script_registry;
mod shared;

#[cfg(feature = "scripts")]
mod library;
#[cfg(feature = "runtime")]
mod runtime;
mod script_registry;

#[cfg(feature = "scripts")]
pub use library::*;
#[cfg(feature = "runtime")]
pub use runtime::*;

#[cfg(feature = "scripts")]
pub use godot_rust_script_derive::{godot_script_impl, GodotScript};

pub mod private_export {
pub use super::script_registry::RemoteVariantType;
pub use super::{script_registry::RemoteVariantType, shared::BindingInit};
pub use abi_stable::std_types::{RStr, RString, RVec};
pub use godot::sys::{plugin_add, plugin_registry};

Expand Down
2 changes: 1 addition & 1 deletion rust-script/src/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ macro_rules! setup_library {
$crate::private_export::plugin_registry!(pub __SCRIPT_REGISTRY: $crate::RegistryItem);

#[no_mangle]
pub fn __godot_rust_script_init(binding: Option<$crate::BindingInit>) -> $crate::private_export::RVec<$crate::RemoteScriptMetaData> {
pub fn __godot_rust_script_init(binding: Option<$crate::private_export::BindingInit>) -> $crate::private_export::RVec<$crate::RemoteScriptMetaData> {
use $crate::private_export::*;
use $crate::godot::obj::EngineEnum;

Expand Down
2 changes: 1 addition & 1 deletion rust-script/src/runtime/hot_reloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use hot_lib_reloader::LibReloadObserver;
use crate::{
apply::Apply,
script_registry::{RemoteGodotScript_TO, RemoteValueRef},
RustScriptLibInit,
shared::RustScriptLibInit,
};

use super::{rust_script::RustScript, HOT_RELOAD_BRIDGE};
Expand Down
93 changes: 93 additions & 0 deletions rust-script/src/runtime/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use std::rc::Rc;

use abi_stable::std_types::RBox;
use godot::{
obj::EngineEnum,
prelude::{
meta::{ClassName, MethodInfo, PropertyInfo},
Array, Dictionary, Gd, Object, StringName, ToGodot,
},
};

use crate::{
apply::Apply,
script_registry::{CreateScriptInstanceData_TO, RemoteGodotScript_TO},
RemoteScriptMetaData,
};

#[derive(Debug)]
pub struct ScriptMetaData {
class_name: ClassName,
base_type_name: StringName,
properties: Rc<Vec<PropertyInfo>>,
methods: Rc<Vec<MethodInfo>>,
create_data: CreateScriptInstanceData_TO<'static, RBox<()>>,
}

impl ScriptMetaData {
pub fn class_name(&self) -> ClassName {
self.class_name
}

pub fn base_type_name(&self) -> StringName {
self.base_type_name.clone()
}

pub fn create_data(&self, base: Gd<Object>) -> RemoteGodotScript_TO<'static, RBox<()>> {
self.create_data.create(base.to_variant().into())
}

pub fn properties(&self) -> Rc<Vec<PropertyInfo>> {
self.properties.clone()
}

pub fn methods(&self) -> Rc<Vec<MethodInfo>> {
self.methods.clone()
}
}

impl From<RemoteScriptMetaData> for ScriptMetaData {
fn from(value: RemoteScriptMetaData) -> Self {
Self {
class_name: ClassName::from_ascii_cstr(value.class_name.as_str().as_bytes()),
base_type_name: StringName::from(value.base_type_name.as_str()),
properties: Rc::new(value.properties.into_iter().map(Into::into).collect()),
methods: Rc::new(value.methods.into_iter().map(Into::into).collect()),
create_data: value.create_data,
}
}
}

pub(super) trait ToDictionary {
fn to_dict(&self) -> Dictionary;
}

impl ToDictionary for PropertyInfo {
fn to_dict(&self) -> Dictionary {
let mut dict = Dictionary::new();

dict.set("name", self.property_name.clone());
dict.set("class_name", self.class_name.to_string_name());
dict.set("type", self.variant_type as i32);
dict.set("hint", self.hint.ord());
dict.set("hint_string", self.hint_string.clone());
dict.set("usage", self.usage.ord());

dict
}
}

impl ToDictionary for MethodInfo {
fn to_dict(&self) -> Dictionary {
Dictionary::new().apply(|dict| {
dict.set("name", self.method_name.clone());
dict.set("flags", self.flags.ord());

let args: Array<_> = self.arguments.iter().map(|arg| arg.to_dict()).collect();

dict.set("args", args);

dict.set("return", self.return_type.to_dict());
})
}
}
59 changes: 8 additions & 51 deletions rust-script/src/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(all(feature = "hot-reload", debug_assertions))]
mod hot_reloader;
mod metadata;
mod resource_loader;
mod resource_saver;
mod rust_script;
Expand All @@ -8,22 +9,18 @@ mod rust_script_language;

use std::{collections::HashMap, rc::Rc, sync::RwLock};

use abi_stable::std_types::RVec;
use cfg_if::cfg_if;
use godot::{
engine::{Engine, ResourceLoader, ResourceSaver},
obj::EngineEnum,
prelude::{
godot_print,
meta::{MethodInfo, PropertyInfo},
Array, Dictionary, Gd,
},
prelude::{godot_print, Gd},
};

use crate::{
apply::Apply,
runtime::{resource_loader::RustScriptResourceLoader, resource_saver::RustScriptResourceSaver},
script_registry::{RemoteScriptMetaData, ScriptMetaData},
runtime::{
metadata::ScriptMetaData, resource_loader::RustScriptResourceLoader,
resource_saver::RustScriptResourceSaver,
},
shared::RustScriptLibInit,
};

use self::rust_script_language::RustScriptLanguage;
Expand All @@ -43,7 +40,7 @@ macro_rules! setup {
#[hot_functions]
extern "Rust" {
pub fn __godot_rust_script_init(
binding: Option<$crate::BindingInit>,
binding: Option<$crate::private_export::BindingInit>,
) -> RVec<$crate::RemoteScriptMetaData>;
}

Expand Down Expand Up @@ -79,12 +76,6 @@ thread_local! {
static HOT_RELOAD_BRIDGE: std::cell::RefCell<HashMap<rust_script_instance::RustScriptInstanceId, std::cell::RefCell<HotReloadEntry>>> = std::cell::RefCell::default();
}

pub type BindingInit = godot::sys::GodotBinding;

pub trait RustScriptLibInit: Fn(Option<BindingInit>) -> RVec<RemoteScriptMetaData> {}

impl<F> RustScriptLibInit for F where F: Fn(Option<BindingInit>) -> RVec<RemoteScriptMetaData> {}

cfg_if! {
if #[cfg(all(feature = "hot-reload", debug_assertions))] {
type HotReloadSubscribe = fn() -> hot_lib_reloader::LibReloadObserver;
Expand Down Expand Up @@ -206,37 +197,3 @@ fn load_rust_scripts(lib_init_fn: Rc<dyn RustScriptLibInit>) {
*reg = registry;
});
}

trait ToDictionary {
fn to_dict(&self) -> Dictionary;
}

impl ToDictionary for PropertyInfo {
fn to_dict(&self) -> Dictionary {
let mut dict = Dictionary::new();

dict.set("name", self.property_name.clone());
dict.set("class_name", self.class_name.to_string_name());
dict.set("type", self.variant_type as i32);
dict.set("hint", self.hint.ord());
dict.set("hint_string", self.hint_string.clone());
dict.set("usage", self.usage.ord());

dict
}
}

impl ToDictionary for MethodInfo {
fn to_dict(&self) -> Dictionary {
Dictionary::new().apply(|dict| {
dict.set("name", self.method_name.clone());
dict.set("flags", self.flags.ord());

let args: Array<_> = self.arguments.iter().map(|arg| arg.to_dict()).collect();

dict.set("args", args);

dict.set("return", self.return_type.to_dict());
})
}
}
3 changes: 2 additions & 1 deletion rust-script/src/runtime/rust_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ use RemoteGodotScript_trait::RemoteGodotScript_TO;
use crate::script_registry::RemoteGodotScript_trait;

use super::{
metadata::ToDictionary,
rust_script_instance::{RustScriptInstance, RustScriptPlaceholder},
rust_script_language::RustScriptLanguage,
ToDictionary, SCRIPT_REGISTRY,
SCRIPT_REGISTRY,
};

#[derive(GodotClass)]
Expand Down
57 changes: 7 additions & 50 deletions rust-script/src/script_registry.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, fmt::Debug, marker::PhantomData, rc::Rc};
use std::{collections::HashMap, fmt::Debug, marker::PhantomData};

use abi_stable::{
sabi_trait::TD_CanDowncast,
Expand All @@ -11,7 +11,7 @@ use godot::{
prelude::{
godot_print,
meta::{ClassName, MethodInfo, PropertyInfo},
Gd, Object, StringName, ToGodot, Variant,
Gd, Object, StringName, Variant,
},
sys::VariantType,
};
Expand Down Expand Up @@ -147,11 +147,11 @@ impl From<RemoteScriptMethodInfo> for MethodInfo {
#[derive(Debug, StableAbi)]
#[repr(C)]
pub struct RemoteScriptMetaData {
class_name: RStr<'static>,
base_type_name: RStr<'static>,
properties: RVec<RemoteScriptPropertyInfo>,
methods: RVec<RemoteScriptMethodInfo>,
create_data: CreateScriptInstanceData_TO<'static, RBox<()>>,
pub(crate) class_name: RStr<'static>,
pub(crate) base_type_name: RStr<'static>,
pub(crate) properties: RVec<RemoteScriptPropertyInfo>,
pub(crate) methods: RVec<RemoteScriptMethodInfo>,
pub(crate) create_data: CreateScriptInstanceData_TO<'static, RBox<()>>,
}

impl RemoteScriptMetaData {
Expand All @@ -175,49 +175,6 @@ impl RemoteScriptMetaData {
}
}

#[derive(Debug)]
pub struct ScriptMetaData {
class_name: ClassName,
base_type_name: StringName,
properties: Rc<Vec<PropertyInfo>>,
methods: Rc<Vec<MethodInfo>>,
create_data: CreateScriptInstanceData_TO<'static, RBox<()>>,
}

impl ScriptMetaData {
pub fn class_name(&self) -> ClassName {
self.class_name
}

pub fn base_type_name(&self) -> StringName {
self.base_type_name.clone()
}

pub fn create_data(&self, base: Gd<Object>) -> RemoteGodotScript_TO<'static, RBox<()>> {
self.create_data.create(base.to_variant().into())
}

pub fn properties(&self) -> Rc<Vec<PropertyInfo>> {
self.properties.clone()
}

pub fn methods(&self) -> Rc<Vec<MethodInfo>> {
self.methods.clone()
}
}

impl From<RemoteScriptMetaData> for ScriptMetaData {
fn from(value: RemoteScriptMetaData) -> Self {
Self {
class_name: ClassName::from_ascii_cstr(value.class_name.as_str().as_bytes()),
base_type_name: StringName::from(value.base_type_name.as_str()),
properties: Rc::new(value.properties.into_iter().map(Into::into).collect()),
methods: Rc::new(value.methods.into_iter().map(Into::into).collect()),
create_data: value.create_data,
}
}
}

#[abi_stable::sabi_trait]
pub trait CreateScriptInstanceData: Debug {
fn create(&self, base: RemoteValue) -> RemoteGodotScript_TO<'static, RBox<()>>;
Expand Down
9 changes: 9 additions & 0 deletions rust-script/src/shared.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use abi_stable::std_types::RVec;

use crate::RemoteScriptMetaData;

pub type BindingInit = godot::sys::GodotBinding;

pub trait RustScriptLibInit: Fn(Option<BindingInit>) -> RVec<RemoteScriptMetaData> {}

impl<F> RustScriptLibInit for F where F: Fn(Option<BindingInit>) -> RVec<RemoteScriptMetaData> {}
Loading

0 comments on commit 54fbe15

Please sign in to comment.