add support for tool class

This commit is contained in:
Michael Angelo Calimlim 2022-11-19 20:12:48 +08:00
parent 1ab32391f5
commit 6a285a45b6
4 changed files with 100 additions and 2 deletions

View file

@ -37,6 +37,12 @@ $ ftw class MyHero Area2D # creates a class that derives from `Area2D`
```
> Note: This creates the following files `rust/src/my_hero.rs`, `godot/scenes/MyHero.tscn` and `godot/native/MyHero.gdns` then adds the class inside `rust/src/lib.rs`. A complete list of node types can be found [here](https://github.com/macalimlim/ftw/blob/main/src/ftw_node_type.rs)
#### Creates a tool class
```shell
$ ftw class MyButtonTool Button # creates a tool class called `MyButtonTool` that is deriving from `Button`
```
> Note: Same as creating a regular class and also take note of having `Tool` at the end of the class name as a convention
##### You could also organize rs, tscn and gdns files into submodules or subfolders
```shell
$ ftw class heros/marvel/avengers/IronMan Area2D # creates a class that derives from `Area2D`
@ -126,7 +132,7 @@ godot-server-exe=godot-server-script # assuming it's on $PATH
### Cross Compilation
You can also enable cross compilation, so you could build and export a game from and to any platform. It uses this [docker image](https://github.com/ufoot/godot-rust-cross-compiler) to set up Linux, Android, Mac iOS and Windows toolchains (WebAssembly toolchains to follow). Please read this [section](https://github.com/macalimlim/godot-rust-cross-compiler#bugs-and-limitations) to know what is currently supported.
You can also enable cross compilation, so you could build and export a game from and to any platform. It uses this [docker image](https://github.com/macalimlim/godot-rust-cross-compiler) to set up Linux, Android, Mac, iOS and Windows toolchains (WebAssembly toolchains to follow). Please read this [section](https://github.com/macalimlim/godot-rust-cross-compiler#bugs-and-limitations) to know what is currently supported.
```ini
[ftw]

View file

@ -512,6 +512,51 @@ mod ftw_command_tests {
.contains("handle.add_class::<my_player::MyPlayer>();"));
}
#[test]
fn test_process_ftw_command_tool_class() {
let project = Project::new();
let cmd = FtwCommand::New {
project_name: project.get_name(),
template: FtwTemplate::default(),
};
let _ = cmd.process();
let _ = env::set_current_dir(Path::new(&project.get_name()));
let cmd = FtwCommand::Class {
class_name: "MyButtonTool".to_string(),
node_type: FtwNodeType::Button,
};
let _ = cmd.process();
let _ = env::set_current_dir(Path::new("../"));
assert!(project.exists("rust/src/my_button_tool.rs"));
assert!(project.exists("godot/native/MyButtonTool.gdns"));
assert!(project.exists("godot/scenes/MyButtonTool.tscn"));
assert!(project.exists("rust/src/lib.rs"));
assert!(project
.read("rust/src/my_button_tool.rs")
.contains("pub struct MyButtonTool"));
assert!(project
.read("rust/src/my_button_tool.rs")
.contains("#[inherit(Button)]"));
assert!(project
.read("godot/native/MyButtonTool.gdns")
.contains("resource_name = \"MyButtonTool\""));
assert!(project
.read("godot/native/MyButtonTool.gdns")
.contains("class_name = \"MyButtonTool\""));
assert!(project.read("godot/scenes/MyButtonTool.tscn").contains(
"[ext_resource path=\"res://native/MyButtonTool.gdns\" type=\"Script\" id=1]"
));
assert!(project
.read("godot/scenes/MyButtonTool.tscn")
.contains("[node name=\"MyButtonTool\" type=\"Button\"]"));
assert!(project
.read("rust/src/lib.rs")
.contains("mod my_button_tool;"));
assert!(project
.read("rust/src/lib.rs")
.contains("handle.add_tool_class::<my_button_tool::MyButtonTool>();"));
}
#[test]
fn test_process_ftw_command_class_with_subs() {
let project = Project::new();

View file

@ -9,7 +9,8 @@ use gdnative::prelude::{godot_init, InitHandle};
fn init(handle: InitHandle) {
{%- assign classes = classes | split: "|" | compact | sort -%}
{%- for class in classes %}
handle.add_class::<{{class}}>();
{%- assign suffix = class | slice: -4, 4 -%}
{%- if suffix == "Tool" -%}handle.add_tool_class::<{{class}}>();{%- else -%}handle.add_class::<{{class}}>();{%- endif %}
{%- endfor %}
}

View file

@ -50,6 +50,52 @@ fn test_ftw_class() {
.contains("handle.add_class::<my_player::MyPlayer>();"));
}
#[test]
fn test_ftw_tool_class() {
let project = Project::new();
ftw()
.arg("new")
.arg(&project.get_name())
.assert()
.success()
.stdout(predicates::str::contains("Done!").from_utf8());
ftw()
.arg("class")
.arg("MyButtonTool")
.arg("Button")
.current_dir(&project.get_name())
.assert()
.success();
assert!(project.exists("rust/src/my_button_tool.rs"));
assert!(project.exists("godot/native/MyButtonTool.gdns"));
assert!(project.exists("godot/scenes/MyButtonTool.tscn"));
assert!(project.exists("rust/src/lib.rs"));
assert!(project
.read("rust/src/my_button_tool.rs")
.contains("pub struct MyButtonTool"));
assert!(project
.read("rust/src/my_button_tool.rs")
.contains("#[inherit(Button)]"));
assert!(project
.read("godot/native/MyButtonTool.gdns")
.contains("resource_name = \"MyButtonTool\""));
assert!(project
.read("godot/native/MyButtonTool.gdns")
.contains("class_name = \"MyButtonTool\""));
assert!(project
.read("godot/scenes/MyButtonTool.tscn")
.contains("[ext_resource path=\"res://native/MyButtonTool.gdns\" type=\"Script\" id=1]"));
assert!(project
.read("godot/scenes/MyButtonTool.tscn")
.contains("[node name=\"MyButtonTool\" type=\"Button\"]"));
assert!(project
.read("rust/src/lib.rs")
.contains("mod my_button_tool;"));
assert!(project
.read("rust/src/lib.rs")
.contains("handle.add_tool_class::<my_button_tool::MyButtonTool>();"));
}
#[test]
fn test_ftw_class_no_node_type() {
let project = Project::new();