Skip to content

Commit 3ad211b

Browse files
committed
Implement #[property(rpc = "mode")]
1 parent ba3ab95 commit 3ad211b

File tree

6 files changed

+76
-46
lines changed

6 files changed

+76
-46
lines changed

gdnative-derive/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use syn::{parse::Parser, AttributeArgs, DeriveInput, ItemFn, ItemImpl, ItemType}
1313
mod methods;
1414
mod native_script;
1515
mod profiled;
16+
mod syntax;
1617
mod utils;
1718
mod varargs;
1819
mod variant;
@@ -268,6 +269,11 @@ pub fn profiled(meta: TokenStream, input: TokenStream) -> TokenStream {
268269
///
269270
/// Hides the property from the editor. Does not prevent it from being sent over network or saved in storage.
270271
///
272+
/// - `rpc = "selected_rpc"`
273+
///
274+
/// Sets the [Multiplayer API RPC Mode](https://docs.godotengine.org/en/stable/classes/class_multiplayerapi.html?highlight=RPC#enumerations) for the property.
275+
/// See the `#[method]` documentation below for possible values and their semantics.
276+
///
271277
/// ### `#[methods]`
272278
/// Adds the necessary information to a an `impl` block to register the properties and methods with Godot.
273279
///

gdnative-derive/src/methods.rs

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,58 +7,13 @@ use proc_macro2::TokenStream as TokenStream2;
77
use quote::{quote, ToTokens};
88
use std::boxed::Box;
99

10+
use crate::syntax::rpc_mode::RpcMode;
1011
use crate::utils::find_non_concrete;
1112

1213
use self::mixin_args::{MixinArgsBuilder, MixinKind};
1314

1415
mod mixin_args;
1516

16-
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
17-
pub enum RpcMode {
18-
Disabled,
19-
Remote,
20-
RemoteSync,
21-
Master,
22-
Puppet,
23-
MasterSync,
24-
PuppetSync,
25-
}
26-
27-
impl RpcMode {
28-
fn parse(s: &str) -> Option<Self> {
29-
match s {
30-
"remote" => Some(RpcMode::Remote),
31-
"remote_sync" => Some(RpcMode::RemoteSync),
32-
"master" => Some(RpcMode::Master),
33-
"puppet" => Some(RpcMode::Puppet),
34-
"disabled" => Some(RpcMode::Disabled),
35-
"master_sync" => Some(RpcMode::MasterSync),
36-
"puppet_sync" => Some(RpcMode::PuppetSync),
37-
_ => None,
38-
}
39-
}
40-
}
41-
42-
impl Default for RpcMode {
43-
fn default() -> Self {
44-
RpcMode::Disabled
45-
}
46-
}
47-
48-
impl ToTokens for RpcMode {
49-
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
50-
match self {
51-
RpcMode::Disabled => tokens.extend(quote!(RpcMode::Disabled)),
52-
RpcMode::Remote => tokens.extend(quote!(RpcMode::Remote)),
53-
RpcMode::RemoteSync => tokens.extend(quote!(RpcMode::RemoteSync)),
54-
RpcMode::Master => tokens.extend(quote!(RpcMode::Master)),
55-
RpcMode::Puppet => tokens.extend(quote!(RpcMode::Puppet)),
56-
RpcMode::MasterSync => tokens.extend(quote!(RpcMode::MasterSync)),
57-
RpcMode::PuppetSync => tokens.extend(quote!(RpcMode::PuppetSync)),
58-
}
59-
}
60-
}
61-
6217
pub(crate) struct ClassMethodExport {
6318
pub(crate) class_ty: Box<Type>,
6419
pub(crate) methods: Vec<ExportMethod>,

gdnative-derive/src/native_script/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ pub(crate) fn derive_native_class(derive_input: &DeriveInput) -> Result<TokenStr
100100
.map(|default_value| quote!(.with_default(#default_value)));
101101
let with_hint = config.hint.map(|hint_fn| quote!(.with_hint(#hint_fn())));
102102
let with_usage = config.no_editor.then(|| quote!(.with_usage(#gdnative_core::export::PropertyUsage::NOEDITOR)));
103+
let with_rpc_mode = config.rpc_mode.map(|rpc_mode| quote!(.with_rpc_mode(#gdnative_core::export::#rpc_mode)));
104+
103105
// check whether this property type is `Property<T>`. if so, extract T from it.
104106
let property_ty = match config.ty {
105107
Type::Path(ref path) => path
@@ -176,6 +178,7 @@ pub(crate) fn derive_native_class(derive_input: &DeriveInput) -> Result<TokenStr
176178
#with_default
177179
#with_hint
178180
#with_usage
181+
#with_rpc_mode
179182
#with_getter
180183
#with_setter
181184
.done();

gdnative-derive/src/native_script/property_args.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use proc_macro2::Span;
22
use std::fmt::Debug;
33
use syn::spanned::Spanned;
44

5+
use crate::syntax::rpc_mode::RpcMode;
6+
57
#[derive(Debug)]
68
pub enum PropertyGet {
79
Default,
@@ -22,6 +24,7 @@ pub struct PropertyAttrArgs {
2224
pub hint: Option<syn::Path>,
2325
pub get: Option<PropertyGet>,
2426
pub set: Option<PropertySet>,
27+
pub rpc_mode: Option<RpcMode>,
2528
pub no_editor: bool,
2629
}
2730

@@ -32,6 +35,7 @@ pub struct PropertyAttrArgsBuilder {
3235
hint: Option<syn::Path>,
3336
get: Option<PropertyGet>,
3437
set: Option<PropertySet>,
38+
rpc_mode: Option<RpcMode>,
3539
no_editor: bool,
3640
}
3741

@@ -44,6 +48,7 @@ impl PropertyAttrArgsBuilder {
4448
hint: None,
4549
get: None,
4650
set: None,
51+
rpc_mode: None,
4752
no_editor: false,
4853
}
4954
}
@@ -125,6 +130,18 @@ impl PropertyAttrArgsBuilder {
125130
"get" => process_path_input!(get, PropertyGet::Owned),
126131
"get_ref" => process_path_input!(get, PropertyGet::Ref),
127132
"set" => process_path_input!(set, PropertySet::WithPath),
133+
"rpc" => {
134+
let rpc = Self::extract_lit_str(&pair.lit)
135+
.ok_or_else(|| Self::err_attr_not_a_string_literal(pair.span(), "rpc"))?;
136+
let rpc = rpc.value();
137+
let rpc = RpcMode::parse(&rpc).ok_or_else(|| {
138+
syn::Error::new(
139+
pair.lit.span(),
140+
format!("unexpected value for `rpc`: {rpc}"),
141+
)
142+
})?;
143+
update_prop!(rpc_mode, rpc)
144+
}
128145
_ => {
129146
return Err(syn::Error::new(
130147
pair.span(),
@@ -167,6 +184,7 @@ impl PropertyAttrArgsBuilder {
167184
hint: self.hint,
168185
get: self.get,
169186
set: self.set,
187+
rpc_mode: self.rpc_mode,
170188
no_editor: self.no_editor,
171189
}
172190
}

gdnative-derive/src/syntax.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod rpc_mode;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use quote::{quote, ToTokens};
2+
3+
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
4+
pub enum RpcMode {
5+
Disabled,
6+
Remote,
7+
RemoteSync,
8+
Master,
9+
Puppet,
10+
MasterSync,
11+
PuppetSync,
12+
}
13+
14+
impl RpcMode {
15+
pub fn parse(s: &str) -> Option<Self> {
16+
match s {
17+
"remote" => Some(RpcMode::Remote),
18+
"remote_sync" => Some(RpcMode::RemoteSync),
19+
"master" => Some(RpcMode::Master),
20+
"puppet" => Some(RpcMode::Puppet),
21+
"disabled" => Some(RpcMode::Disabled),
22+
"master_sync" => Some(RpcMode::MasterSync),
23+
"puppet_sync" => Some(RpcMode::PuppetSync),
24+
_ => None,
25+
}
26+
}
27+
}
28+
29+
impl Default for RpcMode {
30+
fn default() -> Self {
31+
RpcMode::Disabled
32+
}
33+
}
34+
35+
impl ToTokens for RpcMode {
36+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
37+
match self {
38+
RpcMode::Disabled => tokens.extend(quote!(RpcMode::Disabled)),
39+
RpcMode::Remote => tokens.extend(quote!(RpcMode::Remote)),
40+
RpcMode::RemoteSync => tokens.extend(quote!(RpcMode::RemoteSync)),
41+
RpcMode::Master => tokens.extend(quote!(RpcMode::Master)),
42+
RpcMode::Puppet => tokens.extend(quote!(RpcMode::Puppet)),
43+
RpcMode::MasterSync => tokens.extend(quote!(RpcMode::MasterSync)),
44+
RpcMode::PuppetSync => tokens.extend(quote!(RpcMode::PuppetSync)),
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)