feat!: fix some lifetimes in InputContainerInner, almast done one example, add default for plugin, rebase src from crate/bevy_controls to src
This commit is contained in:
@@ -27,7 +27,6 @@ env_logger = "0.10.1"
|
||||
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["crate/*"]
|
||||
exclude = ["example/"]
|
||||
|
||||
[[example]]
|
||||
|
||||
Generated
+199
@@ -336,6 +336,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
"bevy_controls",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1233,6 +1235,20 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "calloop"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"log",
|
||||
"nix 0.25.1",
|
||||
"slotmap",
|
||||
"thiserror",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
@@ -1497,6 +1513,15 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
||||
|
||||
[[package]]
|
||||
name = "dlib"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.0"
|
||||
@@ -2257,6 +2282,24 @@ version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metal"
|
||||
version = "0.26.0"
|
||||
@@ -2379,6 +2422,20 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2899,12 +2956,31 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sctk-adwaita"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"log",
|
||||
"memmap2",
|
||||
"smithay-client-toolkit",
|
||||
"tiny-skia",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.196"
|
||||
@@ -2984,6 +3060,25 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smithay-client-toolkit"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"calloop",
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memmap2",
|
||||
"nix 0.24.3",
|
||||
"pkg-config",
|
||||
"wayland-client",
|
||||
"wayland-cursor",
|
||||
"wayland-protocols",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.2.1"
|
||||
@@ -3009,6 +3104,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strict-num"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.25.0"
|
||||
@@ -3141,6 +3242,31 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"png",
|
||||
"tiny-skia-path",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia-path"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"strict-num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
@@ -3417,6 +3543,57 @@ version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"downcast-rs",
|
||||
"libc",
|
||||
"nix 0.24.3",
|
||||
"scoped-tls",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-commons"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
|
||||
dependencies = [
|
||||
"nix 0.24.3",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-cursor"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
|
||||
dependencies = [
|
||||
"nix 0.24.3",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.29.5"
|
||||
@@ -3428,6 +3605,17 @@ dependencies = [
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
|
||||
dependencies = [
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.67"
|
||||
@@ -3856,7 +4044,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"raw-window-handle",
|
||||
"redox_syscall 0.3.5",
|
||||
"sctk-adwaita",
|
||||
"smithay-client-toolkit",
|
||||
"wasm-bindgen",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-protocols",
|
||||
"wayland-scanner",
|
||||
"web-sys",
|
||||
"windows-sys 0.45.0",
|
||||
@@ -3883,6 +4076,12 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xcursor"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911"
|
||||
|
||||
[[package]]
|
||||
name = "xi-unicode"
|
||||
version = "0.3.0"
|
||||
|
||||
@@ -3,6 +3,14 @@ name = "basic"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default_font = []
|
||||
x11 = ["bevy/x11"]
|
||||
wayland = ["bevy/wayland"]
|
||||
windows = ["bevy/bevy_winit"]
|
||||
|
||||
[dependencies]
|
||||
bevy = "0.12.1"
|
||||
bevy_controls = { path = "./../../crate/bevy_controls" }
|
||||
bevy_controls = { path = "./../../" }
|
||||
strum = "0.25.0"
|
||||
strum_macros = "0.25.3"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,93 @@
|
||||
Copyright 2014-2020 The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,67 @@
|
||||
Fira Code Variable Font
|
||||
=======================
|
||||
|
||||
This download contains Fira Code as both a variable font and static fonts.
|
||||
|
||||
Fira Code is a variable font with this axis:
|
||||
wght
|
||||
|
||||
This means all the styles are contained in a single file:
|
||||
FiraCode-VariableFont_wght.ttf
|
||||
|
||||
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||
in those cases you can use the static font files for Fira Code:
|
||||
static/FiraCode-Light.ttf
|
||||
static/FiraCode-Regular.ttf
|
||||
static/FiraCode-Medium.ttf
|
||||
static/FiraCode-SemiBold.ttf
|
||||
static/FiraCode-Bold.ttf
|
||||
|
||||
Get started
|
||||
-----------
|
||||
|
||||
1. Install the font files you want to use
|
||||
|
||||
2. Use your app's font picker to view the font family and all the
|
||||
available styles
|
||||
|
||||
Learn more about variable fonts
|
||||
-------------------------------
|
||||
|
||||
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||
https://variablefonts.typenetwork.com
|
||||
https://medium.com/variable-fonts
|
||||
|
||||
In desktop apps
|
||||
|
||||
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||
|
||||
Online
|
||||
|
||||
https://developers.google.com/fonts/docs/getting_started
|
||||
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||
|
||||
Installing fonts
|
||||
|
||||
MacOS: https://support.apple.com/en-us/HT201749
|
||||
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||
|
||||
Android Apps
|
||||
|
||||
https://developers.google.com/fonts/docs/android
|
||||
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||
|
||||
License
|
||||
-------
|
||||
Please read the full license text (OFL.txt) to understand the permissions,
|
||||
restrictions and requirements for usage, redistribution, and modification.
|
||||
|
||||
You can use them in your products & projects – print or digital,
|
||||
commercial or otherwise.
|
||||
|
||||
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||
license for all details.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Generated
+85
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1707092692,
|
||||
"narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "faf912b086576fd1a15fca610166c98d47bc667e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1707358215,
|
||||
"narHash": "sha256-Nuhi8KEJ2e+2nTimSyEIPqN5eh7ECVWd+AnPXG6L+SY=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "dd917bb1b67fc049fd56fe6de70266a9ab74a4aa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
rust-overlay = {
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
flake-utils.follows = "flake-utils";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, rust-overlay }:
|
||||
flake-utils.lib.eachDefaultSystem
|
||||
(system:
|
||||
let
|
||||
overlays = [ (import rust-overlay) ];
|
||||
pkgs = import nixpkgs {
|
||||
inherit system overlays;
|
||||
};
|
||||
rustToolchain = (pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml);
|
||||
nativeBuildInputs = with pkgs; [ rustToolchain pkg-config ];
|
||||
buildInputs = with pkgs; [
|
||||
openssl
|
||||
alsa-lib
|
||||
|
||||
vulkan-loader
|
||||
|
||||
xorg.libX11
|
||||
xorg.libXrandr
|
||||
xorg.libXcursor
|
||||
xorg.libXi
|
||||
|
||||
wayland
|
||||
libxkbcommon
|
||||
|
||||
udev
|
||||
shellcheck
|
||||
file
|
||||
];
|
||||
in
|
||||
with pkgs;
|
||||
{
|
||||
devShells.default = mkShell {
|
||||
inherit buildInputs nativeBuildInputs;
|
||||
LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = '1.72.0'
|
||||
+213
-1
@@ -1,3 +1,215 @@
|
||||
fn main() {
|
||||
//! This example illustrates how to create
|
||||
//!
|
||||
//! It displays
|
||||
//!
|
||||
//! Yeah I know, now it's a bit ugly
|
||||
|
||||
use bevy::{
|
||||
diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin},
|
||||
ecs::schedule::States,
|
||||
prelude::*,
|
||||
};
|
||||
use bevy_controls::{
|
||||
contract::{
|
||||
Action, ActionInner, GameState, GameStateInner, InputsContainer, InputsContainerInner,
|
||||
},
|
||||
plugin::ControlsPlugin,
|
||||
resource::{Binding, ButtonCombination, Controls, InputType, Inputs, PlayerInputs},
|
||||
};
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
const FIRA_CODE_PATH: &str = "font/FiraCode/FiraCode-VariableFont_wght.ttf";
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, EnumIter, Clone, Copy)]
|
||||
enum MyAction {
|
||||
MoveForward,
|
||||
MoveBack,
|
||||
MoveLeft,
|
||||
MoveRight,
|
||||
Jump,
|
||||
Interact,
|
||||
Shoot,
|
||||
Scope,
|
||||
}
|
||||
|
||||
impl Action for MyAction {}
|
||||
|
||||
impl ActionInner for MyAction {}
|
||||
|
||||
#[derive(States, PartialEq, Eq, Clone, Hash, Debug, Default)]
|
||||
enum MyGameState {
|
||||
#[default]
|
||||
InGame,
|
||||
}
|
||||
|
||||
impl GameState for MyGameState {}
|
||||
|
||||
impl GameStateInner for MyGameState {}
|
||||
|
||||
#[derive(Resource, Default, Clone)]
|
||||
struct MyInputsContainer {
|
||||
// When the game does not provide multiplayer, one field is enough
|
||||
player_inputs: PlayerInputs<MyAction>,
|
||||
}
|
||||
|
||||
impl InputsContainer<MyAction> for MyInputsContainer {}
|
||||
|
||||
impl InputsContainerInner<MyAction> for MyInputsContainer {
|
||||
fn iter_inputs<'a>(&'a self) -> Box<dyn Iterator<Item = &'a PlayerInputs<MyAction>> + 'a> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn me<'a>(&'a self) -> Option<&'a PlayerInputs<MyAction>> {
|
||||
Some(& self.player_inputs)
|
||||
}
|
||||
|
||||
fn me_mut<'a>(&'a mut self) -> Option<&'a mut PlayerInputs<MyAction>> {
|
||||
Some(&mut self.player_inputs)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((
|
||||
DefaultPlugins.set(AssetPlugin {
|
||||
file_path: "asset".into(),
|
||||
..default()
|
||||
}),
|
||||
ControlsPlugin::<MyAction, MyInputsContainer, MyGameState>::default(),
|
||||
))
|
||||
.add_systems(Startup, (add_bindings, setup))
|
||||
.run();
|
||||
}
|
||||
|
||||
// TODO: default bingings...
|
||||
fn add_bindings(mut controls: ResMut<Controls<MyAction, MyGameState>>) {
|
||||
controls.push(
|
||||
MyAction::MoveForward,
|
||||
Binding::new(ButtonCombination::Single(InputType::Keyboard(KeyCode::W))),
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct TextBlock;
|
||||
|
||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
commands.spawn(Camera2dBundle::default());
|
||||
|
||||
commands.spawn((
|
||||
TextBundle::from_sections([
|
||||
TextSection::new(
|
||||
"Input: ",
|
||||
TextStyle {
|
||||
font: asset_server.load(FIRA_CODE_PATH),
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"A ",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"S ",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"W ",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"D ",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"\nAction: ",
|
||||
TextStyle {
|
||||
font: asset_server.load(FIRA_CODE_PATH),
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"MoveLeft",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"MoveBack",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"MoveForward",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::new(
|
||||
"MoveRight",
|
||||
TextStyle {
|
||||
font_size: 60.0,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
]),
|
||||
TextBlock,
|
||||
));
|
||||
}
|
||||
|
||||
// text sections indexes
|
||||
const A_INDEX: usize = 2;
|
||||
const S_INDEX: usize = 3;
|
||||
const W_INDEX: usize = 4;
|
||||
const D_INDEX: usize = 5;
|
||||
|
||||
const MOVE_LEFT_INDEX: usize = 6;
|
||||
const MOVE_BACK_INDEX: usize = 7;
|
||||
const MOVE_FORWARD_INDEX: usize = 8;
|
||||
const MOVE_RIGHT_INDEX: usize = 9;
|
||||
|
||||
fn text_update_system(
|
||||
mut query: Query<&mut Text, With<TextBlock>>,
|
||||
inputs_container: MyInputsContainer,
|
||||
) {
|
||||
for mut text in &mut query {
|
||||
|
||||
let input_value = inputs_container.me().expect("This is bad").get(MyAction::MoveLeft);
|
||||
if input_value.is_boolean() && input_value.to_boolean() {
|
||||
text.sections[MOVE_LEFT_INDEX].style.color = Color::GOLD;
|
||||
} else {
|
||||
text.sections[MOVE_LEFT_INDEX].style.color = Color::GOLD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn text_update_system(
|
||||
// diagnostics: Res<DiagnosticsStore>,
|
||||
// mut query: Query<&mut Text, With<FpsText>>,
|
||||
// ) {
|
||||
// for mut text in &mut query {
|
||||
// if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) {
|
||||
// if let Some(value) = fps.smoothed() {
|
||||
// // Update the value of the second section
|
||||
// text.sections[1].value = format!("{value:.2}");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
+26
-31
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
CURDIR="$(realpath "$(dirname "$0")")"
|
||||
|
||||
@@ -29,29 +29,6 @@ usage %s <path/to/Cargoctoml>\n
|
||||
exit
|
||||
fi
|
||||
|
||||
generate_combinations() {
|
||||
items="$1"
|
||||
size=$2
|
||||
current=$3
|
||||
combination="$4"
|
||||
|
||||
if [ "$current" -eq "$size" ]; then
|
||||
echo "$combination"
|
||||
return
|
||||
fi
|
||||
|
||||
# Split items into positional parameters
|
||||
set -- $items
|
||||
while [ $# -gt 0 ]; do
|
||||
item=$1
|
||||
shift
|
||||
new_combination="$combination $item"
|
||||
remaining_items="$@"
|
||||
generate_combinations "$remaining_items" $size $(($current + 1)) "$new_combination"
|
||||
set -- "$item" $@
|
||||
done
|
||||
}
|
||||
|
||||
CARGO_PATH="$1"
|
||||
|
||||
if [ -z "$CARGO_PATH" ]; then
|
||||
@@ -63,20 +40,38 @@ if [ -d "$CARGO_PATH" ]; then
|
||||
CARGO_PATH="${CARGO_PATH}/Cargo.toml"
|
||||
fi
|
||||
|
||||
features=$(grep '^\[features\]' "$CARGO_PATH" -A99999999 | grep '^\[' -m 2 -B99999999 | grep -v '^\[' | cut -d '=' -f 1 | grep -v 'default')
|
||||
num_features=$(echo "$features" | wc -w | tr -d ' ')
|
||||
features=$(grep '^\[features\]' $1 -A99999999 | grep '^\[' -m 2 -B99999999 | grep -v '^\[' | cut -d '=' -f 1 | grep -v 'default')
|
||||
|
||||
i=1
|
||||
while [ $i -le $num_features ]; do
|
||||
|
||||
generate_combinations() {
|
||||
local items=($1)
|
||||
local size=$2
|
||||
local current=$3
|
||||
local combination=$4
|
||||
|
||||
if [ $current -eq $size ]; then
|
||||
echo "$combination"
|
||||
return
|
||||
fi
|
||||
|
||||
for ((i = 0; i < ${#items[@]}; ++i)); do
|
||||
new_combination="$combination ${items[$i]}"
|
||||
remaining_items=("${items[@]:0:$i}" "${items[@]:$((i + 1))}")
|
||||
generate_combinations "$(IFS=" "; echo "${remaining_items[*]}")" $size $((current + 1)) "$new_combination"
|
||||
done
|
||||
}
|
||||
|
||||
for ((i = 1; i <= $(wc -w <<< "$features"); ++i)); do
|
||||
echo "Generating combinations of size $i"
|
||||
combos=$(generate_combinations "$features" $i 0 "")
|
||||
echo "$combos" | while IFS= read -r line; do
|
||||
combo=$(echo $line | xargs) # Trim
|
||||
echo "$combos" | while read line
|
||||
do
|
||||
echo "Running clippy with features: $line"
|
||||
combo=$(echo $combo | xargs) # Trim
|
||||
echo "Running clippy with features: $combo"
|
||||
if ! cargo clippy --features "$combo"; then
|
||||
echo "Error found in combination: $combo"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
+105
-37
@@ -1,102 +1,170 @@
|
||||
use std::hash::Hash;
|
||||
|
||||
use bevy_ecs::{system::Resource, schedule::States};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use bevy_ecs::{schedule::States, system::Resource};
|
||||
#[cfg(feature = "inspector-egui")]
|
||||
use bevy_inspector_egui::inspector_options::InspectorOptionsType;
|
||||
use strum::IntoEnumIterator;
|
||||
// #[cfg(all(feature = "reflect", feature = "serialize"))]
|
||||
// use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
#[cfg(feature = "reflect")]
|
||||
use bevy_reflect::{Reflect, TypePath, FromReflect};
|
||||
use bevy_reflect::{FromReflect, Reflect, TypePath};
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use crate::resource::PlayerInputs;
|
||||
|
||||
pub trait ActionInner: 'static + std::marker::Sync + std::marker::Send + PartialEq + Eq + Hash + IntoEnumIterator + Clone + Copy { }
|
||||
pub trait ActionInner:
|
||||
'static
|
||||
+ std::marker::Sync
|
||||
+ std::marker::Send
|
||||
+ PartialEq
|
||||
+ Eq
|
||||
+ Hash
|
||||
+ IntoEnumIterator
|
||||
+ Clone
|
||||
+ Copy
|
||||
{
|
||||
}
|
||||
|
||||
pub trait GameStateInner: 'static + std::marker::Sync + std::marker::Send + States { }
|
||||
pub trait GameStateInner: 'static + std::marker::Sync + std::marker::Send + States + Default {}
|
||||
|
||||
pub trait InputsContainerInner<A: Action>: 'static + std::marker::Sync + std::marker::Send + Resource {
|
||||
pub trait InputsContainerInner<A: Action>:
|
||||
'static + std::marker::Sync + std::marker::Send + Resource + Default
|
||||
{
|
||||
/// The method returning an iterator over references to the PlayerInputs.
|
||||
/// Note: the use of 'a for both the method's lifetime and the returned Iterator's lifetime.
|
||||
fn iter_inputs<'a>(&'a self) -> Box<dyn Iterator<Item = &'a PlayerInputs<A>> + 'a>;
|
||||
/// The method returning an player inputs of this client.
|
||||
fn me<'a>(&self) -> Option<&'a PlayerInputs<A>>;
|
||||
fn me<'a>(&'a self) -> Option<&'a PlayerInputs<A>>;
|
||||
/// The method returning an mutable player inputs of this client.
|
||||
fn me_mut<'a>(&self) -> Option<&'a mut PlayerInputs<A>>;
|
||||
fn me_mut<'a>(&'a mut self) -> Option<&'a mut PlayerInputs<A>>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
pub trait SerializeImpl: Serialize + DeserializeOwned { }
|
||||
pub trait SerializeImpl: Serialize + DeserializeOwned {}
|
||||
|
||||
#[cfg(feature = "reflect")]
|
||||
pub trait ReflectImpl: Reflect + TypePath + FromReflect { }
|
||||
pub trait ReflectImpl: Reflect + TypePath + FromReflect {}
|
||||
|
||||
#[cfg(feature = "inspector-egui")]
|
||||
pub trait InspectorEguiImpl: InspectorOptionsType { }
|
||||
pub trait InspectorEguiImpl: InspectorOptionsType {}
|
||||
|
||||
// ===== Action =====
|
||||
// SAFATY: inspector-egui includes reflect
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
not(feature = "serialize"),
|
||||
not(feature = "reflect"),
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait Action: ActionInner {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
feature = "serialize",
|
||||
not(feature = "reflect"),
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait Action: ActionInner + SerializeImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
not(feature = "serialize"),
|
||||
feature = "reflect",
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait Action: ActionInner + ReflectImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl{}
|
||||
#[cfg(all(
|
||||
feature = "serialize",
|
||||
feature = "reflect",
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
||||
pub trait Action: ActionInner + ReflectImpl + InspectorEguiImpl {}
|
||||
pub trait Action: ActionInner + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
// ===== GameState =====
|
||||
// SAFATY: inspector-egui includes reflect
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
not(feature = "serialize"),
|
||||
not(feature = "reflect"),
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait GameState: GameStateInner {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
feature = "serialize",
|
||||
not(feature = "reflect"),
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
not(feature = "serialize"),
|
||||
feature = "reflect",
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait GameState: GameStateInner + ReflectImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl{}
|
||||
#[cfg(all(
|
||||
feature = "serialize",
|
||||
feature = "reflect",
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
||||
pub trait GameState: GameStateInner + ReflectImpl + InspectorEguiImpl {}
|
||||
pub trait GameState: GameStateInner + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
|
||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
// ===== InputsContainer =====
|
||||
// SAFATY: inspector-egui includes reflect
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
not(feature = "serialize"),
|
||||
not(feature = "reflect"),
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
feature = "serialize",
|
||||
not(feature = "reflect"),
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
#[cfg(all(
|
||||
not(feature = "serialize"),
|
||||
feature = "reflect",
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + ReflectImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl + ReflectImpl{}
|
||||
#[cfg(all(
|
||||
feature = "serialize",
|
||||
feature = "reflect",
|
||||
not(feature = "inspector-egui")
|
||||
))]
|
||||
pub trait InputsContainer<A: Action>:
|
||||
InputsContainerInner<A> + SerializeImpl + ReflectImpl
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + ReflectImpl + InspectorEguiImpl {}
|
||||
pub trait InputsContainer<A: Action>:
|
||||
InputsContainerInner<A> + ReflectImpl + InspectorEguiImpl
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
pub trait InputsContainer<A: Action>:
|
||||
InputsContainerInner<A> + SerializeImpl + ReflectImpl + InspectorEguiImpl
|
||||
{
|
||||
}
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
|
||||
+18
-6
@@ -4,10 +4,20 @@ use bevy_input::{Input, keyboard::KeyCode, mouse::MouseButton};
|
||||
|
||||
use crate::{resource::*, contract::{Action, GameState, InputsContainer}};
|
||||
|
||||
pub struct ControlsPlugin<Action, InputsContainer, GameState> {
|
||||
_action: std::marker::PhantomData<Action>,
|
||||
_inputs_container: std::marker::PhantomData<InputsContainer>,
|
||||
_game_state: std::marker::PhantomData<GameState>,
|
||||
pub struct ControlsPlugin<A, Ic, Gs> {
|
||||
_action: std::marker::PhantomData<A>,
|
||||
_inputs_container: std::marker::PhantomData<Ic>,
|
||||
_game_state: std::marker::PhantomData<Gs>,
|
||||
}
|
||||
|
||||
impl<A, Ic, Gs> Default for ControlsPlugin<A, Ic, Gs> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
_action: std::marker::PhantomData,
|
||||
_inputs_container: std::marker::PhantomData,
|
||||
_game_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
@@ -17,6 +27,8 @@ impl<
|
||||
> Plugin for ControlsPlugin<A, Ic, Gs> {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<Controls<A, Gs>>()
|
||||
.init_resource::<Ic>()
|
||||
.add_state::<Gs>()
|
||||
.add_systems(Update, Self::save_input);
|
||||
|
||||
#[cfg(feature = "reflect")]
|
||||
@@ -34,7 +46,7 @@ impl<
|
||||
fn save_input(
|
||||
keyboard_input: Res<Input<KeyCode>>,
|
||||
mouse_input: Res<Input<MouseButton>>,
|
||||
lobby: ResMut<Ic>,
|
||||
mut lobby: ResMut<Ic>,
|
||||
controls: Res<Controls<A, Gs>>,
|
||||
game_state: Res<State<Gs>>,
|
||||
) {
|
||||
@@ -235,4 +247,4 @@ impl<
|
||||
|
||||
// log::info!("without casting: {:?}", duration);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
+30
-7
@@ -80,6 +80,14 @@ impl<A: Action> PlayerInputs<A> {
|
||||
*self.current.get(&action).unwrap()
|
||||
}
|
||||
|
||||
// TODO
|
||||
// /// Returns current input value for action
|
||||
// ///
|
||||
// /// in any case faster that `get_many` method
|
||||
// pub fn all_active(&self) -> InputValue {
|
||||
// *self.current.iter().filter(|a| {a.})
|
||||
// }
|
||||
|
||||
/// Returns current input values for actions
|
||||
pub fn get_many(&self, actions: Vec<A>) -> Vec<InputValue> {
|
||||
// SAFETY: action is always valid
|
||||
@@ -119,6 +127,8 @@ impl<A: Action> PlayerInputs<A> {
|
||||
}
|
||||
|
||||
/// Set input value to new
|
||||
///
|
||||
/// notice: not recomended to use if you do not know what do you do
|
||||
pub fn forced_set(&mut self, action: A, value: impl Into<InputValue>) {
|
||||
// SAFETY: action is always valid
|
||||
// because we iterate over all actions in `default` method
|
||||
@@ -129,6 +139,8 @@ impl<A: Action> PlayerInputs<A> {
|
||||
|
||||
/// Set input value to new
|
||||
/// if it is not the same InputValue type return `Error()`
|
||||
///
|
||||
/// notice: not recomended to use if you do not know what do you do
|
||||
pub fn set(
|
||||
&mut self,
|
||||
action: A,
|
||||
@@ -150,6 +162,8 @@ impl<A: Action> PlayerInputs<A> {
|
||||
}
|
||||
|
||||
/// Update current inputs
|
||||
///
|
||||
/// notice: not recomended to use if you do not know what do you do
|
||||
pub fn forced_update(&mut self, inputs: Inputs<A>) {
|
||||
*self.previous = self.current.clone().0;
|
||||
*self.current = inputs.0;
|
||||
@@ -158,6 +172,8 @@ impl<A: Action> PlayerInputs<A> {
|
||||
/// Update current inputs
|
||||
/// if any input is not the same InputValue type return `Error()`
|
||||
/// ! remember that it work safely but slow
|
||||
///
|
||||
/// notice: not recomended to use if you do not know what do you do
|
||||
pub fn update(&mut self, inputs: Inputs<A>) -> Result<(), Box<dyn error::Error>> {
|
||||
// SAFETY: action is always valid
|
||||
// because we iterate over all actions in `default` method
|
||||
@@ -222,6 +238,7 @@ common_traits_conditions! {
|
||||
Tap,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ActivationOptions {
|
||||
/// Manner in which input is registered
|
||||
pub mode: ActivationMode,
|
||||
@@ -361,7 +378,7 @@ impl InputValue {
|
||||
matches!(self, InputValue::Float(_))
|
||||
}
|
||||
|
||||
pub fn as_boolean(&self) -> bool {
|
||||
pub fn to_boolean(&self) -> bool {
|
||||
match self {
|
||||
InputValue::Boolean(value) => *value,
|
||||
InputValue::Float(value) => *value > 0.0,
|
||||
@@ -371,6 +388,7 @@ impl InputValue {
|
||||
}
|
||||
|
||||
common_traits_conditions! {
|
||||
#[derive(Clone)]
|
||||
pub struct Bindings<Gs: GameState> {
|
||||
/// List of bindings for action
|
||||
#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))]
|
||||
@@ -450,7 +468,7 @@ impl<Gs: GameState> Bindings<Gs> {
|
||||
common_traits_conditions! {
|
||||
/// Contains all bindings for action
|
||||
/// and different activation options
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct BindingConfig<Gs: GameState> {
|
||||
#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))]
|
||||
pub bindings: Bindings<Gs>,
|
||||
@@ -470,22 +488,26 @@ impl<Gs: GameState> BindingConfig<Gs> {
|
||||
|
||||
common_traits_conditions! {
|
||||
/// Contains all bindings for actions
|
||||
#[derive(Resource)]
|
||||
#[derive(Resource, Clone)]
|
||||
#[cfg_attr(feature = "reflect", reflect(Resource))]
|
||||
// TODO: Add delay for input
|
||||
pub struct Controls<A: Action, Gs: GameState>(#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))] HashMap<A, BindingConfig<Gs>>); // TODO: change HashMap to Vec for faster iteration
|
||||
pub struct Controls<A: Action, Gs: GameState>(#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))] HashMap<A, BindingConfig<Gs>>); // TODO: change HashMap to Vec for faster iteration
|
||||
}
|
||||
|
||||
impl<A: Action, Gs: GameState> Default for Controls<A, Gs> {
|
||||
fn default() -> Self {
|
||||
// TODO: default must create empty controls or fill empty / default BindingConfig on any actions
|
||||
let controls = Self(HashMap::new());
|
||||
let mut controls = HashMap::new();
|
||||
|
||||
for key in A::iter() {
|
||||
controls.insert(key, BindingConfig::default());
|
||||
}
|
||||
|
||||
// If you see this error, you may add new action in menu_actions
|
||||
// or make sure that you have only one Menufor<'a> Action<'a> with the same name in the Menufor<'a> Action<'a>s
|
||||
assert!(validate_hash_map(&controls.0));
|
||||
assert!(validate_hash_map(&controls));
|
||||
|
||||
controls
|
||||
Self(controls)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,6 +520,7 @@ impl<A: Action, Gs: GameState> Controls<A, Gs> {
|
||||
/// Push new binding for action
|
||||
pub fn push(&mut self, action: A, binding: Binding<Gs>) {
|
||||
// TODO: warning if config is not exist yet
|
||||
// TODO: interface for [`ActivationOptions`]
|
||||
self.0
|
||||
.entry(action)
|
||||
.or_insert_with(BindingConfig::default)
|
||||
|
||||
Reference in New Issue
Block a user