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]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = ["crate/*"]
|
|
||||||
exclude = ["example/"]
|
exclude = ["example/"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
|
|||||||
Generated
+199
@@ -336,6 +336,8 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy_controls",
|
"bevy_controls",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1233,6 +1235,20 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
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]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.83"
|
version = "1.0.83"
|
||||||
@@ -1497,6 +1513,15 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
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]]
|
[[package]]
|
||||||
name = "downcast-rs"
|
name = "downcast-rs"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -2257,6 +2282,24 @@ version = "2.7.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
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]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.26.0"
|
version = "0.26.0"
|
||||||
@@ -2379,6 +2422,20 @@ dependencies = [
|
|||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
@@ -2899,12 +2956,31 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
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]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.196"
|
version = "1.0.196"
|
||||||
@@ -2984,6 +3060,25 @@ dependencies = [
|
|||||||
"serde",
|
"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]]
|
[[package]]
|
||||||
name = "smol_str"
|
name = "smol_str"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -3009,6 +3104,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strict-num"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
@@ -3141,6 +3242,31 @@ dependencies = [
|
|||||||
"once_cell",
|
"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]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
@@ -3417,6 +3543,57 @@ version = "0.2.90"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
|
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]]
|
[[package]]
|
||||||
name = "wayland-scanner"
|
name = "wayland-scanner"
|
||||||
version = "0.29.5"
|
version = "0.29.5"
|
||||||
@@ -3428,6 +3605,17 @@ dependencies = [
|
|||||||
"xml-rs",
|
"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]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.67"
|
version = "0.3.67"
|
||||||
@@ -3856,7 +4044,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"redox_syscall 0.3.5",
|
"redox_syscall 0.3.5",
|
||||||
|
"sctk-adwaita",
|
||||||
|
"smithay-client-toolkit",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-commons",
|
||||||
|
"wayland-protocols",
|
||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
@@ -3883,6 +4076,12 @@ dependencies = [
|
|||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xcursor"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xi-unicode"
|
name = "xi-unicode"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|||||||
@@ -3,6 +3,14 @@ name = "basic"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default_font = []
|
||||||
|
x11 = ["bevy/x11"]
|
||||||
|
wayland = ["bevy/wayland"]
|
||||||
|
windows = ["bevy/bevy_winit"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = "0.12.1"
|
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")")"
|
CURDIR="$(realpath "$(dirname "$0")")"
|
||||||
|
|
||||||
@@ -29,29 +29,6 @@ usage %s <path/to/Cargoctoml>\n
|
|||||||
exit
|
exit
|
||||||
fi
|
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"
|
CARGO_PATH="$1"
|
||||||
|
|
||||||
if [ -z "$CARGO_PATH" ]; then
|
if [ -z "$CARGO_PATH" ]; then
|
||||||
@@ -63,20 +40,38 @@ if [ -d "$CARGO_PATH" ]; then
|
|||||||
CARGO_PATH="${CARGO_PATH}/Cargo.toml"
|
CARGO_PATH="${CARGO_PATH}/Cargo.toml"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
features=$(grep '^\[features\]' "$CARGO_PATH" -A99999999 | grep '^\[' -m 2 -B99999999 | grep -v '^\[' | cut -d '=' -f 1 | grep -v 'default')
|
features=$(grep '^\[features\]' $1 -A99999999 | grep '^\[' -m 2 -B99999999 | grep -v '^\[' | cut -d '=' -f 1 | grep -v 'default')
|
||||||
num_features=$(echo "$features" | wc -w | tr -d ' ')
|
|
||||||
|
|
||||||
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"
|
echo "Generating combinations of size $i"
|
||||||
combos=$(generate_combinations "$features" $i 0 "")
|
combos=$(generate_combinations "$features" $i 0 "")
|
||||||
echo "$combos" | while IFS= read -r line; do
|
echo "$combos" | while read line
|
||||||
combo=$(echo $line | xargs) # Trim
|
do
|
||||||
|
echo "Running clippy with features: $line"
|
||||||
|
combo=$(echo $combo | xargs) # Trim
|
||||||
echo "Running clippy with features: $combo"
|
echo "Running clippy with features: $combo"
|
||||||
if ! cargo clippy --features "$combo"; then
|
if ! cargo clippy --features "$combo"; then
|
||||||
echo "Error found in combination: $combo"
|
echo "Error found in combination: $combo"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
i=$((i + 1))
|
|
||||||
done
|
done
|
||||||
|
|||||||
+104
-36
@@ -1,102 +1,170 @@
|
|||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use bevy_ecs::{system::Resource, schedule::States};
|
use bevy_ecs::{schedule::States, system::Resource};
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
#[cfg(feature = "inspector-egui")]
|
#[cfg(feature = "inspector-egui")]
|
||||||
use bevy_inspector_egui::inspector_options::InspectorOptionsType;
|
use bevy_inspector_egui::inspector_options::InspectorOptionsType;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
// #[cfg(all(feature = "reflect", feature = "serialize"))]
|
// #[cfg(all(feature = "reflect", feature = "serialize"))]
|
||||||
// use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
// use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||||
#[cfg(feature = "serialize")]
|
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
|
||||||
#[cfg(feature = "reflect")]
|
#[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;
|
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.
|
/// 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.
|
/// 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>;
|
fn iter_inputs<'a>(&'a self) -> Box<dyn Iterator<Item = &'a PlayerInputs<A>> + 'a>;
|
||||||
/// The method returning an player inputs of this client.
|
/// 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.
|
/// 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")]
|
#[cfg(feature = "serialize")]
|
||||||
pub trait SerializeImpl: Serialize + DeserializeOwned { }
|
pub trait SerializeImpl: Serialize + DeserializeOwned {}
|
||||||
|
|
||||||
#[cfg(feature = "reflect")]
|
#[cfg(feature = "reflect")]
|
||||||
pub trait ReflectImpl: Reflect + TypePath + FromReflect { }
|
pub trait ReflectImpl: Reflect + TypePath + FromReflect {}
|
||||||
|
|
||||||
#[cfg(feature = "inspector-egui")]
|
#[cfg(feature = "inspector-egui")]
|
||||||
pub trait InspectorEguiImpl: InspectorOptionsType { }
|
pub trait InspectorEguiImpl: InspectorOptionsType {}
|
||||||
|
|
||||||
// ===== Action =====
|
// ===== Action =====
|
||||||
// SAFATY: inspector-egui includes reflect
|
// 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 {}
|
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 {}
|
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 {}
|
pub trait Action: ActionInner + ReflectImpl {}
|
||||||
|
|
||||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
#[cfg(all(
|
||||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl{}
|
feature = "serialize",
|
||||||
|
feature = "reflect",
|
||||||
|
not(feature = "inspector-egui")
|
||||||
|
))]
|
||||||
|
pub trait Action: ActionInner + SerializeImpl + ReflectImpl {}
|
||||||
|
|
||||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
#[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"))]
|
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
pub trait Action: ActionInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||||
|
|
||||||
// ===== GameState =====
|
// ===== GameState =====
|
||||||
// SAFATY: inspector-egui includes reflect
|
// 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 {}
|
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 {}
|
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 {}
|
pub trait GameState: GameStateInner + ReflectImpl {}
|
||||||
|
|
||||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
#[cfg(all(
|
||||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl{}
|
feature = "serialize",
|
||||||
|
feature = "reflect",
|
||||||
|
not(feature = "inspector-egui")
|
||||||
|
))]
|
||||||
|
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl {}
|
||||||
|
|
||||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
#[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"))]
|
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===== InputsContainer =====
|
// ===== InputsContainer =====
|
||||||
// SAFATY: inspector-egui includes reflect
|
// 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> {}
|
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 {}
|
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 {}
|
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + ReflectImpl {}
|
||||||
|
|
||||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
#[cfg(all(
|
||||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl + ReflectImpl{}
|
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"))]
|
#[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"))]
|
#[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)]
|
// #[cfg(test)]
|
||||||
// mod test {
|
// mod test {
|
||||||
|
|||||||
+17
-5
@@ -4,10 +4,20 @@ use bevy_input::{Input, keyboard::KeyCode, mouse::MouseButton};
|
|||||||
|
|
||||||
use crate::{resource::*, contract::{Action, GameState, InputsContainer}};
|
use crate::{resource::*, contract::{Action, GameState, InputsContainer}};
|
||||||
|
|
||||||
pub struct ControlsPlugin<Action, InputsContainer, GameState> {
|
pub struct ControlsPlugin<A, Ic, Gs> {
|
||||||
_action: std::marker::PhantomData<Action>,
|
_action: std::marker::PhantomData<A>,
|
||||||
_inputs_container: std::marker::PhantomData<InputsContainer>,
|
_inputs_container: std::marker::PhantomData<Ic>,
|
||||||
_game_state: std::marker::PhantomData<GameState>,
|
_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<
|
impl<
|
||||||
@@ -17,6 +27,8 @@ impl<
|
|||||||
> Plugin for ControlsPlugin<A, Ic, Gs> {
|
> Plugin for ControlsPlugin<A, Ic, Gs> {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<Controls<A, Gs>>()
|
app.init_resource::<Controls<A, Gs>>()
|
||||||
|
.init_resource::<Ic>()
|
||||||
|
.add_state::<Gs>()
|
||||||
.add_systems(Update, Self::save_input);
|
.add_systems(Update, Self::save_input);
|
||||||
|
|
||||||
#[cfg(feature = "reflect")]
|
#[cfg(feature = "reflect")]
|
||||||
@@ -34,7 +46,7 @@ impl<
|
|||||||
fn save_input(
|
fn save_input(
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
mouse_input: Res<Input<MouseButton>>,
|
mouse_input: Res<Input<MouseButton>>,
|
||||||
lobby: ResMut<Ic>,
|
mut lobby: ResMut<Ic>,
|
||||||
controls: Res<Controls<A, Gs>>,
|
controls: Res<Controls<A, Gs>>,
|
||||||
game_state: Res<State<Gs>>,
|
game_state: Res<State<Gs>>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
+30
-7
@@ -80,6 +80,14 @@ impl<A: Action> PlayerInputs<A> {
|
|||||||
*self.current.get(&action).unwrap()
|
*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
|
/// Returns current input values for actions
|
||||||
pub fn get_many(&self, actions: Vec<A>) -> Vec<InputValue> {
|
pub fn get_many(&self, actions: Vec<A>) -> Vec<InputValue> {
|
||||||
// SAFETY: action is always valid
|
// SAFETY: action is always valid
|
||||||
@@ -119,6 +127,8 @@ impl<A: Action> PlayerInputs<A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set input value to new
|
/// 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>) {
|
pub fn forced_set(&mut self, action: A, value: impl Into<InputValue>) {
|
||||||
// SAFETY: action is always valid
|
// SAFETY: action is always valid
|
||||||
// because we iterate over all actions in `default` method
|
// because we iterate over all actions in `default` method
|
||||||
@@ -129,6 +139,8 @@ impl<A: Action> PlayerInputs<A> {
|
|||||||
|
|
||||||
/// Set input value to new
|
/// Set input value to new
|
||||||
/// if it is not the same InputValue type return `Error()`
|
/// 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(
|
pub fn set(
|
||||||
&mut self,
|
&mut self,
|
||||||
action: A,
|
action: A,
|
||||||
@@ -150,6 +162,8 @@ impl<A: Action> PlayerInputs<A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update current inputs
|
/// 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>) {
|
pub fn forced_update(&mut self, inputs: Inputs<A>) {
|
||||||
*self.previous = self.current.clone().0;
|
*self.previous = self.current.clone().0;
|
||||||
*self.current = inputs.0;
|
*self.current = inputs.0;
|
||||||
@@ -158,6 +172,8 @@ impl<A: Action> PlayerInputs<A> {
|
|||||||
/// Update current inputs
|
/// Update current inputs
|
||||||
/// if any input is not the same InputValue type return `Error()`
|
/// if any input is not the same InputValue type return `Error()`
|
||||||
/// ! remember that it work safely but slow
|
/// ! 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>> {
|
pub fn update(&mut self, inputs: Inputs<A>) -> Result<(), Box<dyn error::Error>> {
|
||||||
// SAFETY: action is always valid
|
// SAFETY: action is always valid
|
||||||
// because we iterate over all actions in `default` method
|
// because we iterate over all actions in `default` method
|
||||||
@@ -222,6 +238,7 @@ common_traits_conditions! {
|
|||||||
Tap,
|
Tap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ActivationOptions {
|
pub struct ActivationOptions {
|
||||||
/// Manner in which input is registered
|
/// Manner in which input is registered
|
||||||
pub mode: ActivationMode,
|
pub mode: ActivationMode,
|
||||||
@@ -361,7 +378,7 @@ impl InputValue {
|
|||||||
matches!(self, InputValue::Float(_))
|
matches!(self, InputValue::Float(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_boolean(&self) -> bool {
|
pub fn to_boolean(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
InputValue::Boolean(value) => *value,
|
InputValue::Boolean(value) => *value,
|
||||||
InputValue::Float(value) => *value > 0.0,
|
InputValue::Float(value) => *value > 0.0,
|
||||||
@@ -371,6 +388,7 @@ impl InputValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
common_traits_conditions! {
|
common_traits_conditions! {
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Bindings<Gs: GameState> {
|
pub struct Bindings<Gs: GameState> {
|
||||||
/// List of bindings for action
|
/// List of bindings for action
|
||||||
#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))]
|
#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))]
|
||||||
@@ -450,7 +468,7 @@ impl<Gs: GameState> Bindings<Gs> {
|
|||||||
common_traits_conditions! {
|
common_traits_conditions! {
|
||||||
/// Contains all bindings for action
|
/// Contains all bindings for action
|
||||||
/// and different activation options
|
/// and different activation options
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub struct BindingConfig<Gs: GameState> {
|
pub struct BindingConfig<Gs: GameState> {
|
||||||
#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))]
|
#[cfg_attr(feature = "serialize", serde(bound(deserialize = "")))]
|
||||||
pub bindings: Bindings<Gs>,
|
pub bindings: Bindings<Gs>,
|
||||||
@@ -470,22 +488,26 @@ impl<Gs: GameState> BindingConfig<Gs> {
|
|||||||
|
|
||||||
common_traits_conditions! {
|
common_traits_conditions! {
|
||||||
/// Contains all bindings for actions
|
/// Contains all bindings for actions
|
||||||
#[derive(Resource)]
|
#[derive(Resource, Clone)]
|
||||||
#[cfg_attr(feature = "reflect", reflect(Resource))]
|
#[cfg_attr(feature = "reflect", reflect(Resource))]
|
||||||
// TODO: Add delay for input
|
// 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> {
|
impl<A: Action, Gs: GameState> Default for Controls<A, Gs> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
// TODO: default must create empty controls or fill empty / default BindingConfig on any actions
|
// 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
|
// 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
|
// 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
|
/// Push new binding for action
|
||||||
pub fn push(&mut self, action: A, binding: Binding<Gs>) {
|
pub fn push(&mut self, action: A, binding: Binding<Gs>) {
|
||||||
// TODO: warning if config is not exist yet
|
// TODO: warning if config is not exist yet
|
||||||
|
// TODO: interface for [`ActivationOptions`]
|
||||||
self.0
|
self.0
|
||||||
.entry(action)
|
.entry(action)
|
||||||
.or_insert_with(BindingConfig::default)
|
.or_insert_with(BindingConfig::default)
|
||||||
|
|||||||
Reference in New Issue
Block a user