From d8fa31d6038f4b1535bd3cb98568d79c4e9ccaa4 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 4 Nov 2024 20:02:26 -0500 Subject: [PATCH 1/5] refactor: update & fix unity bindgen --- crates/dojo/bindgen/src/plugins/unity/mod.rs | 28 +++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/crates/dojo/bindgen/src/plugins/unity/mod.rs b/crates/dojo/bindgen/src/plugins/unity/mod.rs index 34ba0cde65..5a21b7944f 100644 --- a/crates/dojo/bindgen/src/plugins/unity/mod.rs +++ b/crates/dojo/bindgen/src/plugins/unity/mod.rs @@ -256,26 +256,36 @@ namespace {namespace} {{ model_struct = Some(token.to_composite().unwrap()); continue; } - - out += UnityPlugin::format_struct(token.to_composite().unwrap()).as_str(); } + let model_struct = model_struct.expect("model struct not found"); + handled_tokens + .iter() + .filter(|(_, s)| { + model_struct.inners.iter().any(|inner| { + inner.token.type_name() == s.type_name() + && inner.token.type_name() != "ByteArray" + }) + }) + .for_each(|(_, s)| { + out += UnityPlugin::format_struct(s).as_str(); + }); + for token in &sorted_enums { if handled_tokens.contains_key(&token.type_path()) { continue; } handled_tokens.insert(token.type_path(), token.to_composite().unwrap().to_owned()); - out += UnityPlugin::format_enum(token.to_composite().unwrap()).as_str(); + if handled_tokens.iter().any(|(_, s)| s.type_name() == token.type_name()) { + out += UnityPlugin::format_enum(token.to_composite().unwrap()).as_str(); + } } out += "\n"; - out += UnityPlugin::format_model( - &get_namespace_from_tag(&model.tag), - model_struct.expect("model struct not found"), - ) - .as_str(); + out += + UnityPlugin::format_model(&get_namespace_from_tag(&model.tag), model_struct).as_str(); out } @@ -477,7 +487,7 @@ namespace {namespace} {{ return await account.ExecuteRaw(new dojo.Call[] {{ new dojo.Call{{ - to = contractAddress, + to = new FieldElement(contractAddress).Inner, selector = \"{system_name}\", calldata = calldata.ToArray() }} From 9d9965f5cd1080e3ec2c68e9a81f7a387ad751db Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 5 Nov 2024 10:40:58 -0500 Subject: [PATCH 2/5] check tokenb in handled tokens --- crates/dojo/bindgen/src/plugins/unity/mod.rs | 36 +++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/crates/dojo/bindgen/src/plugins/unity/mod.rs b/crates/dojo/bindgen/src/plugins/unity/mod.rs index 5a21b7944f..7d394cba83 100644 --- a/crates/dojo/bindgen/src/plugins/unity/mod.rs +++ b/crates/dojo/bindgen/src/plugins/unity/mod.rs @@ -263,7 +263,7 @@ namespace {namespace} {{ .iter() .filter(|(_, s)| { model_struct.inners.iter().any(|inner| { - inner.token.type_name() == s.type_name() + s.r#type == CompositeType::Struct && check_token_in_recursively(&inner.token, &s.type_name()) && inner.token.type_name() != "ByteArray" }) }) @@ -277,11 +277,19 @@ namespace {namespace} {{ } handled_tokens.insert(token.type_path(), token.to_composite().unwrap().to_owned()); - if handled_tokens.iter().any(|(_, s)| s.type_name() == token.type_name()) { - out += UnityPlugin::format_enum(token.to_composite().unwrap()).as_str(); - } } + handled_tokens + .iter() + .filter(|(_, s)| { + model_struct.inners.iter().any(|inner| { + s.r#type == CompositeType::Enum && check_token_in_recursively(&inner.token, &s.type_name()) + }) + }) + .for_each(|(_, s)| { + out += UnityPlugin::format_enum(s).as_str(); + }); + out += "\n"; out += @@ -553,6 +561,26 @@ public class {} : MonoBehaviour {{ } } +fn check_token_in_recursively(token: &Token, type_name: &str) -> bool { + match token { + Token::Composite(composite) => { + if composite.type_name() == type_name { + return true; + } + composite + .inners + .iter() + .any(|inner| check_token_in_recursively(&inner.token, type_name)) + } + Token::Array(array) => check_token_in_recursively(&array.inner, type_name), + Token::Tuple(tuple) => tuple + .inners + .iter() + .any(|inner| check_token_in_recursively(&inner, type_name)), + _ => token.type_name() == type_name + } +} + #[async_trait] impl BuiltinPlugin for UnityPlugin { async fn generate_code(&self, data: &DojoData) -> BindgenResult>> { From 78abe157b9f77095eaec387c7f7fe4df86cd660b Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 5 Nov 2024 10:41:19 -0500 Subject: [PATCH 3/5] fmt --- crates/dojo/bindgen/src/plugins/unity/mod.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/crates/dojo/bindgen/src/plugins/unity/mod.rs b/crates/dojo/bindgen/src/plugins/unity/mod.rs index 7d394cba83..bb3d568ebf 100644 --- a/crates/dojo/bindgen/src/plugins/unity/mod.rs +++ b/crates/dojo/bindgen/src/plugins/unity/mod.rs @@ -263,7 +263,8 @@ namespace {namespace} {{ .iter() .filter(|(_, s)| { model_struct.inners.iter().any(|inner| { - s.r#type == CompositeType::Struct && check_token_in_recursively(&inner.token, &s.type_name()) + s.r#type == CompositeType::Struct + && check_token_in_recursively(&inner.token, &s.type_name()) && inner.token.type_name() != "ByteArray" }) }) @@ -283,7 +284,8 @@ namespace {namespace} {{ .iter() .filter(|(_, s)| { model_struct.inners.iter().any(|inner| { - s.r#type == CompositeType::Enum && check_token_in_recursively(&inner.token, &s.type_name()) + s.r#type == CompositeType::Enum + && check_token_in_recursively(&inner.token, &s.type_name()) }) }) .for_each(|(_, s)| { @@ -567,17 +569,13 @@ fn check_token_in_recursively(token: &Token, type_name: &str) -> bool { if composite.type_name() == type_name { return true; } - composite - .inners - .iter() - .any(|inner| check_token_in_recursively(&inner.token, type_name)) + composite.inners.iter().any(|inner| check_token_in_recursively(&inner.token, type_name)) } Token::Array(array) => check_token_in_recursively(&array.inner, type_name), - Token::Tuple(tuple) => tuple - .inners - .iter() - .any(|inner| check_token_in_recursively(&inner, type_name)), - _ => token.type_name() == type_name + Token::Tuple(tuple) => { + tuple.inners.iter().any(|inner| check_token_in_recursively(&inner, type_name)) + } + _ => token.type_name() == type_name, } } From fb7f6d1db1badb7582b2f35873561aa2c5b14f88 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 5 Nov 2024 11:06:21 -0500 Subject: [PATCH 4/5] final unity bindgen refactor --- crates/dojo/bindgen/src/plugins/unity/mod.rs | 54 ++++++++++---------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/crates/dojo/bindgen/src/plugins/unity/mod.rs b/crates/dojo/bindgen/src/plugins/unity/mod.rs index bb3d568ebf..96f5805467 100644 --- a/crates/dojo/bindgen/src/plugins/unity/mod.rs +++ b/crates/dojo/bindgen/src/plugins/unity/mod.rs @@ -244,6 +244,7 @@ namespace {namespace} {{ let mut sorted_enums = tokens.enums.clone(); sorted_enums.sort_by(compare_tokens_by_type_name); + // Process structs first for token in &sorted_structs { if handled_tokens.contains_key(&token.type_path()) { continue; @@ -251,7 +252,6 @@ namespace {namespace} {{ handled_tokens.insert(token.type_path(), token.to_composite().unwrap().to_owned()); - // first index is our model struct if token.type_name() == naming::get_name_from_tag(&model.tag) { model_struct = Some(token.to_composite().unwrap()); continue; @@ -259,7 +259,9 @@ namespace {namespace} {{ } let model_struct = model_struct.expect("model struct not found"); - handled_tokens + + // Handle struct dependencies + let struct_keys: Vec = handled_tokens .iter() .filter(|(_, s)| { model_struct.inners.iter().any(|inner| { @@ -268,10 +270,16 @@ namespace {namespace} {{ && inner.token.type_name() != "ByteArray" }) }) - .for_each(|(_, s)| { - out += UnityPlugin::format_struct(s).as_str(); - }); + .map(|(k, _)| k.clone()) + .collect(); + + for key in struct_keys { + if let Some(s) = handled_tokens.remove(&key) { + out += UnityPlugin::format_struct(&s).as_str(); + } + } + // Process enums for token in &sorted_enums { if handled_tokens.contains_key(&token.type_path()) { continue; @@ -280,7 +288,8 @@ namespace {namespace} {{ handled_tokens.insert(token.type_path(), token.to_composite().unwrap().to_owned()); } - handled_tokens + // Handle enum dependencies + let enum_keys: Vec = handled_tokens .iter() .filter(|(_, s)| { model_struct.inners.iter().any(|inner| { @@ -288,12 +297,16 @@ namespace {namespace} {{ && check_token_in_recursively(&inner.token, &s.type_name()) }) }) - .for_each(|(_, s)| { - out += UnityPlugin::format_enum(s).as_str(); - }); + .map(|(k, _)| k.clone()) + .collect(); - out += "\n"; + for key in enum_keys { + if let Some(s) = handled_tokens.remove(&key) { + out += UnityPlugin::format_enum(&s).as_str(); + } + } + out += "\n"; out += UnityPlugin::format_model(&get_namespace_from_tag(&model.tag), model_struct).as_str(); @@ -303,11 +316,10 @@ namespace {namespace} {{ // Formats a system into a C# method used by the contract class // Handled tokens should be a list of all structs and enums used by the contract // Such as a set of referenced tokens from a model - fn format_system(system: &Function, handled_tokens: &HashMap) -> String { + fn format_system(system: &Function) -> String { fn handle_arg_recursive( arg_name: &str, token: &Token, - handled_tokens: &HashMap, // variant name // if its an enum variant data enum_variant: Option, @@ -324,8 +336,6 @@ namespace {namespace} {{ match token { Token::Composite(t) => { - let t = handled_tokens.get(&t.type_path).unwrap_or(t); - // Need to flatten the struct members. match t.r#type { CompositeType::Struct if t.type_name() == "ByteArray" => vec![( @@ -339,7 +349,6 @@ namespace {namespace} {{ tokens.extend(handle_arg_recursive( &format!("{}.{}", arg_name, f.name), &f.token, - handled_tokens, enum_variant.clone(), )); }); @@ -380,7 +389,6 @@ namespace {namespace} {{ } else { field.token.clone() }, - handled_tokens, Some(field.name.clone()), )) }); @@ -395,7 +403,6 @@ namespace {namespace} {{ let inner = handle_arg_recursive( &format!("{arg_name}Item"), &array.inner, - handled_tokens, enum_variant.clone(), ); @@ -436,7 +443,6 @@ namespace {namespace} {{ handle_arg_recursive( &format!("{}.Item{}", arg_name, idx + 1), token, - handled_tokens, enum_variant.clone(), ) }) @@ -461,7 +467,7 @@ namespace {namespace} {{ .inputs .iter() .flat_map(|(name, token)| { - let tokens = handle_arg_recursive(name, token, handled_tokens, None); + let tokens = handle_arg_recursive(name, token, None); tokens .iter() @@ -525,11 +531,7 @@ namespace {namespace} {{ // Will format the contract into a C# class and // all systems into C# methods // Handled tokens should be a list of all structs and enums used by the contract - fn handle_contract( - &self, - contract: &DojoContract, - handled_tokens: &HashMap, - ) -> String { + fn handle_contract(&self, contract: &DojoContract) -> String { let mut out = String::new(); out += UnityPlugin::generated_header().as_str(); out += UnityPlugin::contract_imports().as_str(); @@ -539,7 +541,7 @@ namespace {namespace} {{ .iter() // we assume systems dont have outputs .filter(|s| s.to_function().unwrap().get_output_kind() as u8 == FunctionOutputKind::NoOutput as u8) - .map(|system| UnityPlugin::format_system(system.to_function().unwrap(), handled_tokens)) + .map(|system| UnityPlugin::format_system(system.to_function().unwrap())) .collect::>() .join("\n\n "); @@ -608,7 +610,7 @@ impl BuiltinPlugin for UnityPlugin { let contracts_path = Path::new(&format!("Contracts/{}.gen.cs", name)).to_owned(); println!("Generating contract: {}", name); - let code = self.handle_contract(contract, &handled_tokens); + let code = self.handle_contract(contract); out.insert(contracts_path, code.as_bytes().to_vec()); } From 528bdaaa545e5fde3c058cdc7f99d5b8e19674a2 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 5 Nov 2024 11:10:49 -0500 Subject: [PATCH 5/5] clippy --- crates/dojo/bindgen/src/plugins/unity/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/dojo/bindgen/src/plugins/unity/mod.rs b/crates/dojo/bindgen/src/plugins/unity/mod.rs index 96f5805467..2c46accb60 100644 --- a/crates/dojo/bindgen/src/plugins/unity/mod.rs +++ b/crates/dojo/bindgen/src/plugins/unity/mod.rs @@ -575,7 +575,7 @@ fn check_token_in_recursively(token: &Token, type_name: &str) -> bool { } Token::Array(array) => check_token_in_recursively(&array.inner, type_name), Token::Tuple(tuple) => { - tuple.inners.iter().any(|inner| check_token_in_recursively(&inner, type_name)) + tuple.inners.iter().any(|inner| check_token_in_recursively(inner, type_name)) } _ => token.type_name() == type_name, }