-
-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support OnEditor<T>/Required<T>for #[export] similar to OnReady<T> #892
Comments
Agree with this; I noticed the need for something like that and even started experimenting. One thing where I wasn't sure, and it's not obvious from your code either: Should the initialization happen lazily or during |
Personally I would prefer having it in |
Is it guaranteed that |
I did some digging and it seems that lazy |
So the only reason for I'm not saying that's not worth it -- I think these common cases should be as ergonomic as possible -- but I'd like to be clear about the goals 🙂 also then we can find the best possible name. Furthermore, would this only exist for |
Yep. Moreover it would be handy if it could be used for Resources and Refcounted/Objects (almost half of my potential use cases are related to this).
For any I have second thoughts though; it doesn't need to be a part of the core to work (can be external package instead), doesn't point to godot's abstraction directly (read - hard to discover) and implementing such wrapper for Option is trivial (shouldn't take more than 5 to 10 minutes? I pasted my wrapper below anyway). here is my current wrapper, definitively naive (literally an pub struct Required<T> {
inner: Option<T>
}
impl<T> Default for Required<T> {
fn default() -> Self {
Required { inner: None }
}
}
impl<T> std::ops::Deref for Required<T>
{
type Target = T;
fn deref(&self) -> &Self::Target {
match &self.inner {
None => panic!(),
Some(v) => v
}
}
}
impl<T> std::ops::DerefMut for Required<T>
{
fn deref_mut(&mut self) -> &mut Self::Target {
match &mut self.inner {
None => panic!(),
Some(v) => v
}
}
}
impl<T: GodotConvert> GodotConvert for Required<T>
where
Option<T::Via>: GodotType,
{
type Via = Option<T::Via>;
}
impl<T: ToGodot> ToGodot for Required<T>
where
Option<T::Via>: GodotType,
{
fn to_godot(&self) -> Self::Via {
self.inner.to_godot()
}
fn into_godot(self) -> Self::Via {
self.inner.into_godot()
}
fn to_variant(&self) -> Variant {
self.inner.to_variant()
}
}
impl<T: FromGodot> FromGodot for Required<T>
where
Option<T::Via>: GodotType,
{
fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
match Option::<T>::try_from_godot(via) {
Ok(val) => Ok( Required { inner: val }),
Err(e) => Err(e)
}
}
fn from_godot(via: Self::Via) -> Self {
Required { inner: Option::<T>::from_godot(via) }
}
fn try_from_variant(variant: &Variant) -> Result<Self, ConvertError> {
Ok(Required {inner: Option::<T>::try_from_variant(variant)?})
}
fn from_variant(variant: &Variant) -> Self {
return Required {inner: Option::<T>::from_variant(variant)}
}
}
impl<T> Var for Required<T>
where
T: Var + FromGodot,
Option<T>: GodotConvert<Via = Option<T::Via>>,
Required<T>: GodotConvert<Via = Option<T::Via>>
{
fn get_property(&self) -> Self::Via {
Option::<T>::get_property(&self.inner)
}
fn set_property(&mut self, value: Self::Via) {
Option::<T>::set_property(&mut self.inner, value as Self::Via);
}
}
impl<T> Export for Required<T>
where
T: Export + GodotType,
T::Ffi: GodotNullableFfi,
Option<T>: Var,
Required<T>: Var
{
fn default_export_info() -> PropertyHintInfo {
Option::<T>::default_export_info()
}
} |
Currently the pattern for structs with Gd references to other nodes looks like:
Thus forcing user to abuse the
.unwrap()
.Similar case in gdscript can be represented as:
It would be great to create abstraction similar to OnReady<Gd> for required exports. The inner workings would be similar to OnReady, while the exported property itself could be represented by simple
Required<Gd<Node>>
.The text was updated successfully, but these errors were encountered: