Compare commits

...

4 Commits

15 changed files with 150 additions and 100 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/android/
rust/target
/addons/boids/lib/*
/boids-release.zip

View File

@ -11,8 +11,8 @@ it can handle about 2000 boids in a single flock at 11ms physics process tick on
download it from the [asset library](https://godotengine.org/asset-library/asset/3284).
or clone the repository, and run `rust/package-release.sh` to build the libraries for all supported targets.
(requires [cross](https://github.com/cross-rs/cross))
or clone the repository, and run `just build-all` to build the libraries (in release mode) for all supported targets.
(requires [cross](https://github.com/cross-rs/cross), [just](https://github.com/casey/just) and [nushell](https://github.com/nushell/nushell))
## development

View File

@ -4,15 +4,14 @@ compatibility_minimum = 4.3
reloadable = true
[libraries]
linux.debug.x86_64 = "res://addons/boids/lib/boids.x86.so"
windows.debug.x86_64 = "res://addons/boids/lib/boids.x86.dll"
web.debug.wasm32 = "res://addons/boids/lib/boids.wasm"
linux.release.x86_64 = "res://addons/boids/lib/boids.x86.so"
windows.release.x86_64 = "res://addons/boids/lib/boids.x86.dll"
macos.release = "res://addons/boids/lib/libboids.x86.dylib"
linux.debug.x86_64 = "res://addons/boids/lib/boids.x86_64.so"
linux.release.x86_64 = "res://addons/boids/lib/boids.x86_64.so"
windows.debug.x86_64 = "res://addons/boids/lib/boids.x86_64.dll"
windows.release.x86_64 = "res://addons/boids/lib/boids.x86_64.dll"
macos.release = "res://addons/boids/lib/libboids.x86_64.dylib"
macos.release.arm64 = "res://addons/boids/lib/libboids.arm64.dylib"
web.debug.wasm32 = "res://rust/target/wasm32-unknown-emscripten/debug/boids.wasm"
web.release.wasm32 = "res://addons/boids/lib/boids.wasm"
web.debug.wasm32 = "res://addons/boids/lib/boids.wasm32.wasm"
web.release.wasm32 = "res://addons/boids/lib/boids.wasm32.wasm"
[icons]
BoidProperties = "res://addons/boids/resources/boid_properties.svg"

View File

@ -62,3 +62,45 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
[preset.1]
name="Web"
platform="Web"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path=""
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.1.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=true
variant/thread_support=true
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/custom_html_shell=""
html/head_include=""
html/canvas_resize_policy=2
html/focus_canvas_on_start=true
html/experimental_virtual_keyboard=false
progressive_web_app/enabled=false
progressive_web_app/ensure_cross_origin_isolation_headers=true
progressive_web_app/offline_page=""
progressive_web_app/display=1
progressive_web_app/orientation=0
progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)

32
justfile Normal file
View File

@ -0,0 +1,32 @@
set shell := ['nu', '-c']
profile := 'dev'
host-target := `rustc -vV | lines | skip 1 | to text | from csv -s : --noheaders | reduce -f {} {|el, acc| $acc | upsert $el.column0 $el.column1 } | get host`
artifact-dir := 'addons/boids/lib'
[private]
default: (just-cmd '-l')
[private]
setup-env:
mkdir -v {{artifact-dir}}
[private]
just-cmd *FLAGS="":
@just -f {{justfile()}} {{FLAGS}}
build ext $target=(host-target) *FLAGS="": setup-env
cd rust; cross build {{FLAGS}} --profile {{profile}} --target {{target}}
mv -f rust/target/{{target}}/{{ if profile == 'dev' { 'debug' } else { profile } }}/{{ if target =~ 'linux' { 'lib' } else { '' } }}boids.{{ext}} {{artifact-dir}}/boids.{{`$env.target | split row - | first`}}.{{ext}}
build-wasm: (build 'wasm' 'wasm32-unknown-emscripten' '+nightly' '-Zbuild-std')
build-windows: (build 'dll' 'x86_64-pc-windows-msvc')
build-linux: (build 'so' 'x86_64-unknown-linux-gnu')
build-all: (just-cmd '--timestamp' 'profile=release' 'build-linux' 'build-windows' 'build-wasm')
package:
run-external 'zip' '-r' 'boids-release.zip' 'addons' 'examples' 'README.md' 'LICENSE.txt'

90
rust/Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "aho-corasick"
@ -67,8 +67,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "gdextension-api"
version = "0.2.0"
source = "git+https://github.com/godot-rust/godot4-prebuilt?branch=releases#6d902e8a6060007f4ab94cd78882247ae2558d96"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8707eca996b28193b772a4a9a28a97364bb93c97e3c313542e812f2963fb93"
[[package]]
name = "gensym"
@ -101,8 +102,9 @@ checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94"
[[package]]
name = "godot"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8a90179fdd02c52d3d0ac1fbf724c5cb51391f4e207651d105de12e4bda1b6e"
dependencies = [
"godot-core",
"godot-macros",
@ -110,21 +112,24 @@ dependencies = [
[[package]]
name = "godot-bindings"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4172322f6d35c46c657b3de80900a8bdc8937cff4bc3b8559d47c74eb91f0304"
dependencies = [
"gdextension-api",
]
[[package]]
name = "godot-cell"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5070ea39cbc64f6b7ed01c752a550999b08b5244aea4f3c4525e51a9f18a1"
[[package]]
name = "godot-codegen"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22edb4e0e638be594ba199b860290bf092f83d1d166a18d03f75b9d3add66db9"
dependencies = [
"godot-bindings",
"heck",
@ -136,8 +141,9 @@ dependencies = [
[[package]]
name = "godot-core"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2111d99582c537ab65666b725697f85d5c9f8630ec7d0b1d2620c0e95e8e7182"
dependencies = [
"glam",
"godot-bindings",
@ -148,8 +154,9 @@ dependencies = [
[[package]]
name = "godot-ffi"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b01c965bd5189988c7bc7c13ddb02fe4181856ed6a59072ae23029aacce4188"
dependencies = [
"gensym",
"godot-bindings",
@ -160,8 +167,9 @@ dependencies = [
[[package]]
name = "godot-macros"
version = "0.1.3"
source = "git+https://github.com/godot-rust/gdext?branch=master#7634fe769d1fcb66209586f0b6c06aac40978253"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0be00fe849f158b0f9e330fc54fc5d0f41385c30ea2ed1c59a2d031b3c43726"
dependencies = [
"godot-bindings",
"markdown",
@ -172,9 +180,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.14.5"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]]
name = "heck"
@ -184,9 +192,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indexmap"
version = "2.4.0"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
"hashbrown",
@ -194,15 +202,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.158"
version = "0.2.166"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36"
[[package]]
name = "markdown"
version = "1.0.0-alpha.20"
version = "1.0.0-alpha.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "911a8325e6fb87b89890cd4529a2ab34c2669c026279e61c26b7140a3d821ccb"
checksum = "a6491e6c702bf7e3b24e769d800746d5f2c06a6c6a2db7992612e0f429029e81"
dependencies = [
"unicode-id",
]
@ -236,9 +244,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "proc-macro2"
version = "1.0.86"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
@ -274,9 +282,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.6"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@ -286,9 +294,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.7"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@ -297,9 +305,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc-hash"
@ -309,9 +317,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
[[package]]
name = "syn"
version = "2.0.76"
version = "2.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
dependencies = [
"proc-macro2",
"quote",
@ -320,21 +328,21 @@ dependencies = [
[[package]]
name = "unicode-id"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f"
checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561"
[[package]]
name = "unicode-ident"
version = "1.0.12"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "uuid"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [
"getrandom",
]

View File

@ -10,14 +10,14 @@ crate-type = ["cdylib"]
stats = []
[dependencies]
godot = { git = "https://github.com/godot-rust/gdext", branch = "master", features = ["api-4-3", "register-docs"] }
godot = { version = "0.2", features = ["api-4-3", "register-docs"] }
glam = { version = "0.28", features = ["fast-math"] }
rayon = { version = "1.10" }
rustc-hash = "2"
indexmap = "2.4.0"
[target.wasm32-unknown-emscripten.dependencies]
godot = { git = "https://github.com/godot-rust/gdext", branch = "master", features = ["api-4-3", "register-docs", "experimental-wasm", "lazy-function-tables"] }
godot = { version = "0.2", features = ["api-4-3", "register-docs", "experimental-wasm", "lazy-function-tables"] }
[profile.dev]
opt-level = 1

View File

@ -1,10 +0,0 @@
#!/bin/sh
set -x
cargo build
cd ..
cp -f rust/target/debug/libboids.so addons/boids/lib/boids.x86.so
cp -f rust/target/debug/boids.dll addons/boids/lib/boids.x86.dll

View File

@ -1,15 +0,0 @@
#!/bin/sh
set -x
cross build --release --target x86_64-unknown-linux-gnu
cross build --release --target x86_64-pc-windows-gnu
cross +nightly build -Zbuild-std --release --target wasm32-unknown-emscripten
cd ..
cp -f rust/target/x86_64-unknown-linux-gnu/release/libboids.so addons/boids/lib/boids.x86.so
cp -f rust/target/x86_64-pc-windows-gnu/release/boids.dll addons/boids/lib/boids.x86.dll
cp -f rust/target/wasm32-unknown-emscripten/release/boids.wasm addons/boids/lib/boids.wasm
zip -r ../boids-release.zip addons examples README.md LICENSE.txt

View File

@ -72,9 +72,8 @@ impl INode2D for Boid2D {
}
fn exit_tree(&mut self) {
let mut flock = godot::global::instance_from_id(self.get_flock_id())
.unwrap()
.cast::<Flock2D>();
let mut flock: Gd<Flock2D> =
Gd::from_instance_id(InstanceId::from_i64(self.get_flock_id()));
flock.bind_mut().unregister_boid(self.get_id());
}
}

View File

@ -71,9 +71,8 @@ impl INode3D for Boid3D {
}
fn exit_tree(&mut self) {
let mut flock = godot::global::instance_from_id(self.get_flock_id())
.unwrap()
.cast::<Flock3D>();
let mut flock: Gd<Flock3D> =
Gd::from_instance_id(InstanceId::from_i64(self.get_flock_id()));
flock.bind_mut().unregister_boid(self.get_id());
}
}

View File

@ -46,12 +46,12 @@ pub fn calculate_boid(
boid_vel: Vec3,
boid_props: BoidProperties,
flock_props: FlockProperties,
boids: Arc<Vec<(Vec3, Vec3)>>,
other_boids: Arc<Vec<(Vec3, Vec3)>>,
target_position: Option<Vec3>,
) -> Vec3 {
//godot::godot_print!("[Boids] executing from thread {:?}", rayon::current_thread_index());
let mut calced = boids
let mut calced = other_boids
.par_iter()
.fold(CalcArgs::identity, |mut acc, (aboid_pos, aboid_vel)| {
let dist = boid_pos.distance_squared(*aboid_pos);

View File

@ -24,7 +24,7 @@ pub struct Flock2D {
impl Flock2D {
pub fn register_boid(&mut self, boid_id: i64) {
let boid: Gd<Boid2D> = godot::global::instance_from_id(boid_id).unwrap().cast();
let boid: Gd<Boid2D> = Gd::from_instance_id(InstanceId::from_i64(boid_id));
self.boids.insert(boid_id, boid.clone());
get_singleton().bind_mut().register_boid_2d(boid_id, boid);
let flock_id = self.get_id();

View File

@ -26,7 +26,7 @@ pub struct Flock3D {
impl Flock3D {
pub fn register_boid(&mut self, boid_id: i64) {
let boid: Gd<Boid3D> = godot::global::instance_from_id(boid_id).unwrap().cast();
let boid: Gd<Boid3D> = Gd::from_instance_id(InstanceId::from_i64(boid_id));
self.boids.insert(boid_id, boid.clone());
get_singleton().bind_mut().register_boid_3d(boid_id, boid);
let flock_id = self.get_id();

View File

@ -25,13 +25,9 @@ type FxIndexMap<K, V> = IndexMap<K, V, FxBuildHasher>;
const SINGLETON_NAME: &str = "Boids";
fn get_singleton_name() -> StringName {
StringName::from(SINGLETON_NAME)
}
fn get_singleton() -> Gd<Boids> {
Engine::singleton()
.get_singleton(get_singleton_name())
.get_singleton(SINGLETON_NAME)
.unwrap()
.cast()
}
@ -43,8 +39,8 @@ unsafe impl ExtensionLibrary for BoidsExtension {
fn on_level_init(level: InitLevel) {
match level {
InitLevel::Scene => {
let singleton = Boids::new_alloc().upcast::<Object>();
Engine::singleton().register_singleton(get_singleton_name(), singleton);
let singleton = Boids::new_alloc();
Engine::singleton().register_singleton(SINGLETON_NAME, &singleton);
}
_ => (),
}
@ -54,18 +50,17 @@ unsafe impl ExtensionLibrary for BoidsExtension {
if level == InitLevel::Scene {
// Get the `Engine` instance and `StringName` for your singleton.
let mut engine = Engine::singleton();
let singleton_name = get_singleton_name();
// We need to retrieve the pointer to the singleton object,
// as it has to be freed manually - unregistering singleton
// doesn't do it automatically.
let singleton = engine
.get_singleton(singleton_name.clone())
.get_singleton(SINGLETON_NAME)
.expect("cannot retrieve the singleton");
// Unregistering singleton and freeing the object itself is needed
// to avoid memory leaks and warnings, especially for hot reloading.
engine.unregister_singleton(singleton_name);
engine.unregister_singleton(SINGLETON_NAME);
singleton.free();
}
}
@ -140,7 +135,7 @@ struct Boids {
impl Boids {
fn register_flock_2d(&mut self, flock_id: i64) {
let flock = godot::global::instance_from_id(flock_id).unwrap().cast();
let flock = Gd::from_instance_id(InstanceId::from_i64(flock_id));
self.flocks2d.insert(flock_id, flock);
godot_print!("[Boids] flock {flock_id} registered");
}
@ -161,7 +156,7 @@ impl Boids {
}
fn register_flock_3d(&mut self, flock_id: i64) {
let flock = godot::global::instance_from_id(flock_id).unwrap().cast();
let flock = Gd::from_instance_id(InstanceId::from_i64(flock_id));
self.flocks3d.insert(flock_id, flock);
godot_print!("[Boids] flock {flock_id} registered");
}