mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Merge branch 'master' into tilemapdata
This commit is contained in:
@@ -15,6 +15,11 @@
|
||||
history.bin
|
||||
settings.ron
|
||||
|
||||
# Nix/NixOS
|
||||
.direnv/
|
||||
.envrc
|
||||
!flake.lock
|
||||
|
||||
# from https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
# 0.36.1
|
||||
|
||||
Minor release with fixes for some annoying bugs.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Fixed frustum culling issues for meshes.
|
||||
- Correctly mark inheritable properties as modified when animating them.
|
||||
- Show selected item in the asset browser when clearing selection text.
|
||||
- Fixed incorrect width of the node removal dialog.
|
||||
- Fixed physics desynchronization issue.
|
||||
- Fixed docking manager layout saving and loading.
|
||||
- Improved project name validation (in both `fyrox-template` and the project manager).
|
||||
- Fixed example shader in the documentation.
|
||||
- Added names for floating panels in the editor—fixes incorrect layout after loading.
|
||||
|
||||
# 0.36
|
||||
|
||||
This version unifies versions of sub-crates - now all sub-crates have the same version. This makes it easier to migrate
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyroxed"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
license = "MIT"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
@@ -13,6 +13,6 @@ readme = "README.md"
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
|
||||
|
||||
[dependencies]
|
||||
fyrox = { version = "0.36.0", path = "../fyrox" }
|
||||
fyroxed_base = { version = "0.36.0", path = "../editor" }
|
||||
fyrox = { version = "0.36.2", path = "../fyrox" }
|
||||
fyroxed_base = { version = "0.36.2", path = "../editor" }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "fyroxed_base"
|
||||
license = "MIT"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.80"
|
||||
@@ -13,8 +13,8 @@ readme = "README.md"
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md", "/resources/**/*"]
|
||||
|
||||
[dependencies]
|
||||
fyrox = { version = "0.36.0", path = "../fyrox", default-features = false }
|
||||
fyrox-build-tools = { version = "0.36.0", path = "../fyrox-build-tools" }
|
||||
fyrox = { version = "0.36.2", path = "../fyrox", default-features = false }
|
||||
fyrox-build-tools = { version = "0.36.2", path = "../fyrox-build-tools" }
|
||||
lazy_static = "1.4.0"
|
||||
ron = "0.8.0"
|
||||
serde = "^1.0.0"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
+22
-17
@@ -53,9 +53,12 @@ use crate::{
|
||||
scroll_viewer::{ScrollViewerBuilder, ScrollViewerMessage},
|
||||
searchbar::{SearchBarBuilder, SearchBarMessage},
|
||||
stack_panel::StackPanelBuilder,
|
||||
style::{resource::StyleResourceExt, Style},
|
||||
text::TextMessage,
|
||||
text_box::TextBoxBuilder,
|
||||
utils::make_simple_tooltip,
|
||||
utils::{
|
||||
make_dropdown_list_option, make_image_button_with_tooltip, make_simple_tooltip,
|
||||
},
|
||||
widget::{WidgetBuilder, WidgetMessage},
|
||||
window::{WindowBuilder, WindowMessage, WindowTitle},
|
||||
wrap_panel::WrapPanelBuilder,
|
||||
@@ -72,18 +75,15 @@ use crate::{
|
||||
utils::window_content,
|
||||
Message, Mode,
|
||||
};
|
||||
use fyrox::gui::style::resource::StyleResourceExt;
|
||||
use fyrox::gui::style::Style;
|
||||
use fyrox::gui::utils::{make_dropdown_list_option, make_image_button_with_tooltip};
|
||||
use notify::{EventKind, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
fs::File,
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
mpsc::{self, Sender},
|
||||
Arc,
|
||||
},
|
||||
@@ -547,7 +547,8 @@ pub struct AssetBrowser {
|
||||
item_to_select: Option<PathBuf>,
|
||||
inspector: AssetInspector,
|
||||
context_menu: ContextMenu,
|
||||
selected_path: PathBuf,
|
||||
current_path: PathBuf,
|
||||
selected_item_path: PathBuf,
|
||||
watcher: Option<RecommendedWatcher>,
|
||||
dependency_viewer: DependencyViewer,
|
||||
resource_creator: Option<ResourceCreator>,
|
||||
@@ -757,7 +758,7 @@ impl AssetBrowser {
|
||||
item_to_select: None,
|
||||
inspector,
|
||||
context_menu,
|
||||
selected_path: Default::default(),
|
||||
current_path: Default::default(),
|
||||
add_resource,
|
||||
resource_creator: None,
|
||||
preview_cache: AssetPreviewCache::new(preview_receiver, 4),
|
||||
@@ -766,6 +767,7 @@ impl AssetBrowser {
|
||||
preview_generators: AssetPreviewGeneratorsCollection::new(),
|
||||
refresh,
|
||||
watcher,
|
||||
selected_item_path: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,8 +889,8 @@ impl AssetBrowser {
|
||||
) {
|
||||
if let Some(watcher) = self.watcher.as_mut() {
|
||||
// notify 6.1.1 crashes otherwise
|
||||
if self.selected_path.exists() {
|
||||
Log::verify(watcher.unwatch(&self.selected_path));
|
||||
if self.current_path.exists() {
|
||||
Log::verify(watcher.unwatch(&self.current_path));
|
||||
}
|
||||
if path.exists() {
|
||||
Log::verify(watcher.watch(path, RecursiveMode::NonRecursive));
|
||||
@@ -897,7 +899,7 @@ impl AssetBrowser {
|
||||
}
|
||||
}
|
||||
|
||||
self.selected_path = path.to_path_buf();
|
||||
self.current_path = path.to_path_buf();
|
||||
self.refresh(ui, resource_manager, message_sender);
|
||||
}
|
||||
|
||||
@@ -914,7 +916,7 @@ impl AssetBrowser {
|
||||
self.clear_assets(ui);
|
||||
|
||||
// Add "return" item.
|
||||
if let Some(mut parent_path) = make_relative_path(&self.selected_path)
|
||||
if let Some(mut parent_path) = make_relative_path(&self.current_path)
|
||||
.ok()
|
||||
.and_then(|path| path.parent().map(|path| path.to_owned()))
|
||||
{
|
||||
@@ -946,7 +948,7 @@ impl AssetBrowser {
|
||||
let mut resources = Vec::new();
|
||||
|
||||
// Get all supported assets from folder and generate previews for them.
|
||||
if let Ok(dir_iter) = std::fs::read_dir(&self.selected_path) {
|
||||
if let Ok(dir_iter) = std::fs::read_dir(&self.current_path) {
|
||||
for entry in dir_iter.flatten() {
|
||||
if let Ok(entry_path) = make_relative_path(entry.path()) {
|
||||
if entry_path.is_dir() {
|
||||
@@ -962,7 +964,7 @@ impl AssetBrowser {
|
||||
}
|
||||
|
||||
// Collect built-in resource (only if the root folder is selected).
|
||||
if let Ok(path) = self.selected_path.canonicalize() {
|
||||
if let Ok(path) = self.current_path.canonicalize() {
|
||||
if let Ok(working_dir) = std::env::current_dir().and_then(|dir| dir.canonicalize()) {
|
||||
if path == working_dir {
|
||||
let built_in_resources = resource_manager
|
||||
@@ -1028,7 +1030,7 @@ impl AssetBrowser {
|
||||
message,
|
||||
engine,
|
||||
sender.clone(),
|
||||
&self.selected_path,
|
||||
&self.current_path,
|
||||
);
|
||||
if asset_added {
|
||||
self.refresh(
|
||||
@@ -1058,6 +1060,8 @@ impl AssetBrowser {
|
||||
.path
|
||||
.clone();
|
||||
|
||||
self.selected_item_path = asset_path.clone();
|
||||
|
||||
self.inspector.inspect_resource_import_options(
|
||||
&asset_path,
|
||||
ui,
|
||||
@@ -1114,7 +1118,8 @@ impl AssetBrowser {
|
||||
&& message.direction() == MessageDirection::FromWidget
|
||||
{
|
||||
if search_text.is_empty() {
|
||||
let path = self.selected_path.clone();
|
||||
let path = self.selected_item_path.parent().unwrap().to_path_buf();
|
||||
self.item_to_select = Some(self.selected_item_path.clone());
|
||||
self.set_path(&path, ui, &engine.resource_manager, &sender);
|
||||
} else {
|
||||
self.clear_assets(ui);
|
||||
|
||||
+54
-15
@@ -316,6 +316,7 @@ pub enum Mode {
|
||||
Build {
|
||||
queue: VecDeque<CommandDescriptor>,
|
||||
process: Option<std::process::Child>,
|
||||
play_after_build: bool,
|
||||
},
|
||||
Play {
|
||||
process: std::process::Child,
|
||||
@@ -573,6 +574,7 @@ pub struct Editor {
|
||||
pub surface_data_viewer: Option<SurfaceDataViewer>,
|
||||
pub processed_ui_messages: usize,
|
||||
pub styles: FxHashMap<EditorStyle, StyleResource>,
|
||||
pub running_game_process: Option<(std::process::Child, Arc<AtomicBool>)>,
|
||||
}
|
||||
|
||||
impl Editor {
|
||||
@@ -983,6 +985,7 @@ impl Editor {
|
||||
surface_data_viewer: None,
|
||||
processed_ui_messages: 0,
|
||||
styles,
|
||||
running_game_process: None,
|
||||
};
|
||||
|
||||
if let Some(data) = startup_data {
|
||||
@@ -1139,7 +1142,9 @@ impl Editor {
|
||||
} else if hot_key == key_bindings.load_scene {
|
||||
sender.send(Message::OpenLoadSceneDialog);
|
||||
} else if hot_key == key_bindings.run_game {
|
||||
sender.send(Message::SwitchToBuildMode);
|
||||
sender.send(Message::SwitchToBuildMode {
|
||||
play_after_build: true,
|
||||
});
|
||||
} else if hot_key == key_bindings.save_scene {
|
||||
if let Some(entry) = self.scenes.current_scene_entry_ref() {
|
||||
if let Some(path) = entry.path.as_ref() {
|
||||
@@ -1315,6 +1320,11 @@ impl Editor {
|
||||
self.build_window = build_window.handle_ui_message(message, ui, || {
|
||||
self.message_sender.send(Message::SwitchToEditMode)
|
||||
});
|
||||
if self.build_window.is_none() {
|
||||
if let Some((process, active)) = self.running_game_process.take() {
|
||||
self.mode = Mode::Play { process, active };
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(export_window) = self.export_window.as_mut() {
|
||||
export_window.handle_ui_message(message, ui, &self.message_sender);
|
||||
@@ -1549,9 +1559,9 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_build_mode(&mut self) {
|
||||
if !matches!(self.mode, Mode::Edit) {
|
||||
Log::err("Cannot enter build mode when from non-Edit mode!");
|
||||
fn set_build_mode(&mut self, play_after_build: bool) {
|
||||
if matches!(self.mode, Mode::Build { .. }) {
|
||||
Log::err("Cannot enter build mode when another build mode is active!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1581,10 +1591,24 @@ impl Editor {
|
||||
.cloned()
|
||||
.collect::<VecDeque<_>>();
|
||||
|
||||
self.mode = Mode::Build {
|
||||
queue,
|
||||
process: None,
|
||||
};
|
||||
let old_mode = std::mem::replace(
|
||||
&mut self.mode,
|
||||
Mode::Build {
|
||||
queue,
|
||||
process: None,
|
||||
play_after_build,
|
||||
},
|
||||
);
|
||||
|
||||
match old_mode {
|
||||
Mode::Edit => {}
|
||||
Mode::Build { .. } => {
|
||||
unreachable!();
|
||||
}
|
||||
Mode::Play { process, active } => {
|
||||
self.running_game_process = Some((process, active));
|
||||
}
|
||||
}
|
||||
|
||||
let ui = self.engine.user_interfaces.first_mut();
|
||||
self.build_window = Some(BuildWindow::new("your game", &mut ui.build_ctx()));
|
||||
@@ -2156,6 +2180,7 @@ impl Editor {
|
||||
Mode::Build {
|
||||
ref mut process,
|
||||
ref mut queue,
|
||||
play_after_build,
|
||||
} => {
|
||||
if process.is_none() {
|
||||
if let Some(build_command) = queue.pop_front() {
|
||||
@@ -2197,14 +2222,26 @@ impl Editor {
|
||||
Log::err("Failed to build the game!");
|
||||
self.mode = Mode::Edit;
|
||||
self.on_mode_changed();
|
||||
} else if queue.is_empty() {
|
||||
} else if queue.is_empty() && play_after_build {
|
||||
self.set_play_mode();
|
||||
} else {
|
||||
if let Some(build_window) = self.build_window.as_mut() {
|
||||
build_window.reset(self.engine.user_interfaces.first());
|
||||
let ui = self.engine.user_interfaces.first();
|
||||
if queue.is_empty() {
|
||||
if let Some(build_window) = self.build_window.take() {
|
||||
build_window.destroy(ui);
|
||||
}
|
||||
if let Some((process, active)) =
|
||||
self.running_game_process.take()
|
||||
{
|
||||
self.mode = Mode::Play { process, active };
|
||||
}
|
||||
} else {
|
||||
if let Some(build_window) = self.build_window.as_mut() {
|
||||
build_window.reset(ui);
|
||||
}
|
||||
// Continue on next command.
|
||||
*process = None;
|
||||
}
|
||||
// Continue on next command.
|
||||
*process = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2384,10 +2421,12 @@ impl Editor {
|
||||
.world_viewer
|
||||
.try_locate_object(handle, self.engine.user_interfaces.first()),
|
||||
Message::SwitchMode => match self.mode {
|
||||
Mode::Edit => self.set_build_mode(),
|
||||
Mode::Edit => self.set_build_mode(true),
|
||||
_ => self.set_editor_mode(),
|
||||
},
|
||||
Message::SwitchToBuildMode => self.set_build_mode(),
|
||||
Message::SwitchToBuildMode { play_after_build } => {
|
||||
self.set_build_mode(play_after_build)
|
||||
}
|
||||
Message::SwitchToEditMode => self.set_editor_mode(),
|
||||
Message::OpenLoadSceneDialog => {
|
||||
self.menu
|
||||
|
||||
@@ -78,7 +78,9 @@ pub enum Message {
|
||||
SetCurrentScene(Uuid),
|
||||
FocusObject(Handle<Node>),
|
||||
SetEditorCameraProjection(Projection),
|
||||
SwitchToBuildMode,
|
||||
SwitchToBuildMode {
|
||||
play_after_build: bool,
|
||||
},
|
||||
SwitchToEditMode,
|
||||
SwitchMode,
|
||||
OpenLoadSceneDialog,
|
||||
|
||||
@@ -39,11 +39,16 @@ use crate::{
|
||||
message::{MessageDirection, MouseButton, UiMessage},
|
||||
numeric::{NumericUpDownBuilder, NumericUpDownMessage},
|
||||
stack_panel::StackPanelBuilder,
|
||||
style::{resource::StyleResourceExt, Style},
|
||||
tab_control::{
|
||||
Tab, TabControl, TabControlBuilder, TabControlMessage, TabDefinition, TabUserData,
|
||||
},
|
||||
text::{TextBuilder, TextMessage},
|
||||
utils::make_simple_tooltip,
|
||||
utils::{
|
||||
make_dropdown_list_option, make_dropdown_list_option_universal,
|
||||
make_dropdown_list_option_with_height, make_image_button_with_tooltip,
|
||||
make_simple_tooltip,
|
||||
},
|
||||
vec::{Vec3EditorBuilder, Vec3EditorMessage},
|
||||
widget::{WidgetBuilder, WidgetMessage},
|
||||
window::{WindowBuilder, WindowMessage, WindowTitle},
|
||||
@@ -64,12 +69,6 @@ use crate::{
|
||||
DropdownListBuilder, GameScene, Message, Mode, SaveSceneConfirmationDialogAction,
|
||||
SceneContainer, Settings,
|
||||
};
|
||||
use fyrox::gui::style::resource::StyleResourceExt;
|
||||
use fyrox::gui::style::Style;
|
||||
use fyrox::gui::utils::{
|
||||
make_dropdown_list_option, make_dropdown_list_option_universal,
|
||||
make_dropdown_list_option_with_height, make_image_button_with_tooltip,
|
||||
};
|
||||
use std::{
|
||||
ops::Deref,
|
||||
sync::mpsc::{self, Receiver},
|
||||
@@ -281,6 +280,7 @@ pub struct SceneViewer {
|
||||
interaction_modes: FxHashMap<Uuid, Handle<UiNode>>,
|
||||
camera_projection: Handle<UiNode>,
|
||||
play: Handle<UiNode>,
|
||||
build: Handle<UiNode>,
|
||||
stop: Handle<UiNode>,
|
||||
build_profile: Handle<UiNode>,
|
||||
sender: MessageSender,
|
||||
@@ -305,6 +305,7 @@ impl SceneViewer {
|
||||
let selection_frame;
|
||||
let camera_projection;
|
||||
let play;
|
||||
let build;
|
||||
let stop;
|
||||
let build_profile;
|
||||
|
||||
@@ -376,6 +377,10 @@ impl SceneViewer {
|
||||
.with_orientation(Orientation::Horizontal)
|
||||
.build(ctx);
|
||||
|
||||
let build_tooltip = "Build Project.\nBuilds the game, but does not run it. Could be \
|
||||
useful for hot reloading - change the source code and then press this button. The new version \
|
||||
of the game DLL will be built and automagically loaded by the editor and the running game.";
|
||||
|
||||
let top_ribbon = GridBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
.with_child(interaction_mode_panel)
|
||||
@@ -411,7 +416,8 @@ impl SceneViewer {
|
||||
play = ButtonBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
.with_margin(Thickness::uniform(1.0))
|
||||
.with_width(26.0),
|
||||
.with_width(26.0)
|
||||
.with_tooltip(make_simple_tooltip(ctx, "Play")),
|
||||
)
|
||||
.with_content(
|
||||
ImageBuilder::new(
|
||||
@@ -429,6 +435,29 @@ impl SceneViewer {
|
||||
.build(ctx);
|
||||
play
|
||||
})
|
||||
.with_child({
|
||||
build = ButtonBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
.with_margin(Thickness::uniform(1.0))
|
||||
.with_width(26.0)
|
||||
.with_tooltip(make_simple_tooltip(ctx, build_tooltip)),
|
||||
)
|
||||
.with_content(
|
||||
ImageBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
.with_width(16.0)
|
||||
.with_height(16.0)
|
||||
.with_margin(Thickness::uniform(4.0))
|
||||
.with_background(
|
||||
Brush::Solid(Color::opaque(0, 200, 0)).into(),
|
||||
),
|
||||
)
|
||||
.with_opt_texture(load_image!("../../resources/hammer.png"))
|
||||
.build(ctx),
|
||||
)
|
||||
.build(ctx);
|
||||
build
|
||||
})
|
||||
.with_child({
|
||||
stop = ButtonBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
@@ -571,6 +600,7 @@ impl SceneViewer {
|
||||
scene_gizmo_image,
|
||||
debug_switches,
|
||||
grid_snap_menu,
|
||||
build,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -717,7 +747,13 @@ impl SceneViewer {
|
||||
}
|
||||
|
||||
if message.destination() == self.play {
|
||||
self.sender.send(Message::SwitchToBuildMode);
|
||||
self.sender.send(Message::SwitchToBuildMode {
|
||||
play_after_build: true,
|
||||
});
|
||||
} else if message.destination() == self.build {
|
||||
self.sender.send(Message::SwitchToBuildMode {
|
||||
play_after_build: false,
|
||||
});
|
||||
} else if message.destination() == self.stop {
|
||||
self.sender.send(Message::SwitchToEditMode);
|
||||
}
|
||||
|
||||
Generated
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1739866667,
|
||||
"narHash": "sha256-EO1ygNKZlsAC9avfcwHkKGMsmipUk1Uc0TbrEZpkn64=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "73cf49b8ad837ade2de76f87eb53fc85ed5d4680",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1740074384,
|
||||
"narHash": "sha256-T2eO9ognlph94/TyAu1uILo38fZG1G4S5FQxG+YBDv0=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "d291a120b6524911249b198baf3ec3e07ff57e04",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
rust-overlay = {
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = {
|
||||
nixpkgs,
|
||||
rust-overlay,
|
||||
...
|
||||
}:
|
||||
let
|
||||
overlays = [
|
||||
(import rust-overlay)
|
||||
];
|
||||
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
];
|
||||
|
||||
forAllSystems = f:
|
||||
nixpkgs.lib.genAttrs systems
|
||||
(system: f { pkgs = import nixpkgs { inherit system overlays; }; });
|
||||
in
|
||||
{
|
||||
devShells = forAllSystems ({ pkgs }: with pkgs; {
|
||||
default = mkShell rec {
|
||||
buildInputs = [
|
||||
rust-bin.stable.latest.default
|
||||
|
||||
pkg-config
|
||||
xorg.libxcb
|
||||
alsa-lib
|
||||
wayland
|
||||
libxkbcommon
|
||||
libGL
|
||||
];
|
||||
LD_LIBRARY_PATH = "${lib.makeLibraryPath buildInputs}";
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-animation"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -15,8 +15,8 @@ readme = "README.md"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { version = "0.36.0", path = "../fyrox-core" }
|
||||
fyrox-resource = { version = "0.36.0", path = "../fyrox-resource" }
|
||||
fyrox-core = { version = "0.36.2", path = "../fyrox-core" }
|
||||
fyrox-resource = { version = "0.36.2", path = "../fyrox-resource" }
|
||||
strum = "0.26.1"
|
||||
strum_macros = "0.26.1"
|
||||
fxhash = "0.2.1"
|
||||
|
||||
@@ -235,7 +235,7 @@ impl TrackValue {
|
||||
|
||||
/// Tries to perform a numeric type casting of the current value to some other and returns a boxed value, that can
|
||||
/// be used to set the value using reflection.
|
||||
pub fn apply_to_any(&self, any: &mut dyn Any, value_type: ValueType) {
|
||||
pub fn apply_to_any(&self, any: &mut dyn Any, value_type: ValueType) -> bool {
|
||||
fn convert_vec2<T>(vec2: &Vector2<f32>) -> Vector2<T>
|
||||
where
|
||||
f32: AsPrimitive<T>,
|
||||
@@ -260,17 +260,19 @@ impl TrackValue {
|
||||
Vector4::new(vec4.x.as_(), vec4.y.as_(), vec4.z.as_(), vec4.w.as_())
|
||||
}
|
||||
|
||||
fn set<T>(any: &mut dyn Any, value: T)
|
||||
fn set<T>(any: &mut dyn Any, value: T) -> bool
|
||||
where
|
||||
T: Any + Copy,
|
||||
{
|
||||
if let Some(boolean) = any.downcast_mut::<T>() {
|
||||
*boolean = value;
|
||||
if let Some(any_val) = any.downcast_mut::<T>() {
|
||||
*any_val = value;
|
||||
true
|
||||
} else {
|
||||
Log::err(format!(
|
||||
"Animation: unable to set value of type {}! Types mismatch!",
|
||||
any::type_name::<T>()
|
||||
))
|
||||
));
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +289,7 @@ impl TrackValue {
|
||||
ValueType::I16 => set(any, *real as i16),
|
||||
ValueType::U8 => set(any, *real as u8),
|
||||
ValueType::I8 => set(any, *real as i8),
|
||||
_ => (),
|
||||
_ => false,
|
||||
},
|
||||
TrackValue::Vector2(vec2) => match value_type {
|
||||
ValueType::Vector2Bool => set(any, Vector2::new(vec2.x.ne(&0.0), vec2.y.ne(&0.0))),
|
||||
@@ -301,7 +303,7 @@ impl TrackValue {
|
||||
ValueType::Vector2I16 => set(any, convert_vec2::<i16>(vec2)),
|
||||
ValueType::Vector2U8 => set(any, convert_vec2::<u8>(vec2)),
|
||||
ValueType::Vector2I8 => set(any, convert_vec2::<i8>(vec2)),
|
||||
_ => (),
|
||||
_ => false,
|
||||
},
|
||||
TrackValue::Vector3(vec3) => match value_type {
|
||||
ValueType::Vector3Bool => set(
|
||||
@@ -318,7 +320,7 @@ impl TrackValue {
|
||||
ValueType::Vector3I16 => set(any, convert_vec3::<i16>(vec3)),
|
||||
ValueType::Vector3U8 => set(any, convert_vec3::<u8>(vec3)),
|
||||
ValueType::Vector3I8 => set(any, convert_vec3::<i8>(vec3)),
|
||||
_ => (),
|
||||
_ => false,
|
||||
},
|
||||
TrackValue::Vector4(vec4) => match value_type {
|
||||
ValueType::Vector4Bool => set(
|
||||
@@ -340,12 +342,12 @@ impl TrackValue {
|
||||
ValueType::Vector4I16 => set(any, convert_vec4::<i16>(vec4)),
|
||||
ValueType::Vector4U8 => set(any, convert_vec4::<u8>(vec4)),
|
||||
ValueType::Vector4I8 => set(any, convert_vec4::<i8>(vec4)),
|
||||
_ => (),
|
||||
_ => false,
|
||||
},
|
||||
TrackValue::UnitQuaternion(quat) => match value_type {
|
||||
ValueType::UnitQuaternionF32 => set(any, *quat),
|
||||
ValueType::UnitQuaternionF64 => set(any, quat.cast::<f64>()),
|
||||
_ => (),
|
||||
_ => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -410,9 +412,19 @@ impl BoundValue {
|
||||
) {
|
||||
object.as_reflect_mut(&mut |object_ref| {
|
||||
object_ref.resolve_path_mut(property_path, &mut |result| match result {
|
||||
Ok(property) => property.as_any_mut(&mut |any| {
|
||||
self.value.apply_to_any(any, value_type);
|
||||
}),
|
||||
Ok(property) => {
|
||||
let mut applied = false;
|
||||
property.as_any_mut(&mut |any| {
|
||||
applied = self.value.apply_to_any(any, value_type);
|
||||
});
|
||||
if applied {
|
||||
property.as_inheritable_variable_mut(&mut |var| {
|
||||
if let Some(var) = var {
|
||||
var.mark_modified();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
Log::err(format!(
|
||||
"Failed to set property {property_path}! Reason: {err:?}"
|
||||
@@ -459,11 +471,21 @@ pub fn negate_unit_quaternion(a: &UnitQuaternion<f32>) -> UnitQuaternion<f32> {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::value::{BoundValue, TrackValue, ValueBinding, ValueType};
|
||||
use fyrox_core::reflect::prelude::*;
|
||||
use fyrox_core::{reflect::prelude::*, variable::InheritableVariable};
|
||||
|
||||
#[derive(Default, Reflect, Debug, PartialEq)]
|
||||
#[derive(Reflect, Debug, PartialEq)]
|
||||
struct OtherStruct {
|
||||
field: u32,
|
||||
inheritable_variable: InheritableVariable<u32>,
|
||||
}
|
||||
|
||||
impl Default for OtherStruct {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
field: 0,
|
||||
inheritable_variable: InheritableVariable::new_non_modified(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Reflect, Debug, PartialEq)]
|
||||
@@ -499,6 +521,14 @@ mod test {
|
||||
value: TrackValue::Real(123.0),
|
||||
};
|
||||
|
||||
let inheritable_variable_value = BoundValue {
|
||||
binding: ValueBinding::Property {
|
||||
name: "inheritable_variable".into(),
|
||||
value_type: ValueType::U32,
|
||||
},
|
||||
value: TrackValue::Real(123.0),
|
||||
};
|
||||
|
||||
let mut object = MyStruct::default();
|
||||
|
||||
some_bool_value.apply_to_object(&mut object, "some_bool", ValueType::Bool);
|
||||
@@ -509,5 +539,14 @@ mod test {
|
||||
|
||||
field_value.apply_to_object(&mut object, "other_struct.field", ValueType::U32);
|
||||
assert_eq!(object.other_struct.field, 123);
|
||||
|
||||
assert!(!object.other_struct.inheritable_variable.is_modified());
|
||||
inheritable_variable_value.apply_to_object(
|
||||
&mut object,
|
||||
"other_struct.inheritable_variable",
|
||||
ValueType::U32,
|
||||
);
|
||||
assert_eq!(object.other_struct.field, 123);
|
||||
assert!(object.other_struct.inheritable_variable.is_modified());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-build-tools"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Build tools for Fyrox Engine"
|
||||
@@ -13,7 +13,7 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0" }
|
||||
fyrox-ui = { path = "../fyrox-ui", version = "0.36.0" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2" }
|
||||
fyrox-ui = { path = "../fyrox-ui", version = "0.36.2" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.2" }
|
||||
serde = { version = "1.0.215", features = ["derive"] }
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-core-derive"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["toyboot4e <[email protected]>, Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-core"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -15,8 +15,8 @@ readme = "README.md"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core-derive = { path = "../fyrox-core-derive", version = "0.36.0" }
|
||||
fyrox-math = { path = "../fyrox-math", version = "0.36.0" }
|
||||
fyrox-core-derive = { path = "../fyrox-core-derive", version = "0.36.2" }
|
||||
fyrox-math = { path = "../fyrox-math", version = "0.36.2" }
|
||||
base64 = "0.22.1"
|
||||
byteorder = "1.4.3"
|
||||
rand = "0.8.4"
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
//! friendliness.
|
||||
|
||||
use crate::{reflect::prelude::*, visitor::prelude::*, ComponentProvider};
|
||||
use std::cell::UnsafeCell;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
fmt::Debug,
|
||||
future::Future,
|
||||
marker::PhantomData,
|
||||
ops::{Index, IndexMut},
|
||||
sync::atomic::{self, AtomicIsize},
|
||||
};
|
||||
|
||||
pub mod handle;
|
||||
@@ -184,15 +184,22 @@ where
|
||||
// Zero - non-borrowed.
|
||||
// Negative values - amount of mutable borrows, positive - amount of immutable borrows.
|
||||
#[derive(Default, Debug)]
|
||||
struct RefCounter(pub AtomicIsize);
|
||||
struct RefCounter(pub UnsafeCell<isize>);
|
||||
|
||||
unsafe impl Sync for RefCounter {}
|
||||
unsafe impl Send for RefCounter {}
|
||||
|
||||
impl RefCounter {
|
||||
fn increment(&self) {
|
||||
self.0.fetch_add(1, atomic::Ordering::Relaxed);
|
||||
unsafe fn get(&self) -> isize {
|
||||
*self.0.get()
|
||||
}
|
||||
|
||||
fn decrement(&self) {
|
||||
self.0.fetch_sub(1, atomic::Ordering::Relaxed);
|
||||
unsafe fn increment(&self) {
|
||||
*self.0.get() += 1;
|
||||
}
|
||||
|
||||
unsafe fn decrement(&self) {
|
||||
*self.0.get() -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,14 +20,13 @@
|
||||
|
||||
use super::{Handle, PayloadContainer, Pool, RefCounter};
|
||||
use crate::ComponentProvider;
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::{
|
||||
any::TypeId,
|
||||
cell::RefCell,
|
||||
cmp::Ordering,
|
||||
fmt::{Debug, Display, Formatter},
|
||||
marker::PhantomData,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::atomic,
|
||||
};
|
||||
|
||||
pub struct Ref<'a, 'b, T>
|
||||
@@ -64,7 +63,11 @@ where
|
||||
T: ?Sized,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
self.ref_counter.decrement();
|
||||
// SAFETY: This is safe, because this ref lifetime is managed by the borrow checker,
|
||||
// so it cannot outlive the pool record.
|
||||
unsafe {
|
||||
self.ref_counter.decrement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +114,11 @@ where
|
||||
T: ?Sized,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
self.ref_counter.increment();
|
||||
// SAFETY: This is safe, because this ref lifetime is managed by the borrow checker,
|
||||
// so it cannot outlive the pool record.
|
||||
unsafe {
|
||||
self.ref_counter.increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +236,7 @@ where
|
||||
return Err(MultiBorrowError::InvalidHandleGeneration(handle));
|
||||
}
|
||||
|
||||
let current_ref_count = record.ref_counter.0.load(atomic::Ordering::Relaxed);
|
||||
let current_ref_count = unsafe { record.ref_counter.get() };
|
||||
if current_ref_count < 0 {
|
||||
return Err(MultiBorrowError::MutablyBorrowed(handle));
|
||||
}
|
||||
@@ -241,16 +248,8 @@ where
|
||||
return Err(MultiBorrowError::Empty(handle));
|
||||
};
|
||||
|
||||
if let Err(ref_count) = record.ref_counter.0.compare_exchange(
|
||||
current_ref_count,
|
||||
current_ref_count + 1,
|
||||
atomic::Ordering::Acquire,
|
||||
atomic::Ordering::Relaxed,
|
||||
) {
|
||||
// This might happen if other thread have already acquired the mutable reference.
|
||||
if ref_count < 0 {
|
||||
return Err(MultiBorrowError::MutablyBorrowed(handle));
|
||||
}
|
||||
unsafe {
|
||||
record.ref_counter.increment();
|
||||
}
|
||||
|
||||
Ok(Ref {
|
||||
@@ -299,7 +298,9 @@ where
|
||||
return Err(MultiBorrowError::InvalidHandleGeneration(handle));
|
||||
}
|
||||
|
||||
let current_ref_count = record.ref_counter.0.load(atomic::Ordering::Relaxed);
|
||||
// SAFETY: It is safe to access the counter because of borrow checker guarantees that
|
||||
// the record is alive.
|
||||
let current_ref_count = unsafe { record.ref_counter.get() };
|
||||
match current_ref_count.cmp(&0) {
|
||||
Ordering::Less => {
|
||||
return Err(MultiBorrowError::MutablyBorrowed(handle));
|
||||
@@ -317,21 +318,10 @@ where
|
||||
return Err(MultiBorrowError::Empty(handle));
|
||||
};
|
||||
|
||||
if let Err(ref_count) = record.ref_counter.0.compare_exchange(
|
||||
0,
|
||||
-1,
|
||||
atomic::Ordering::Acquire,
|
||||
atomic::Ordering::Relaxed,
|
||||
) {
|
||||
match ref_count.cmp(&0) {
|
||||
Ordering::Less => {
|
||||
return Err(MultiBorrowError::MutablyBorrowed(handle));
|
||||
}
|
||||
Ordering::Greater => {
|
||||
return Err(MultiBorrowError::ImmutablyBorrowed(handle));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
// SAFETY: It is safe to access the counter because of borrow checker guarantees that
|
||||
// the record is alive.
|
||||
unsafe {
|
||||
record.ref_counter.decrement();
|
||||
}
|
||||
|
||||
Ok(RefMut {
|
||||
@@ -364,22 +354,18 @@ where
|
||||
return Err(MultiBorrowError::InvalidHandleGeneration(handle));
|
||||
}
|
||||
|
||||
// Acquire temporary lock.
|
||||
if let Err(ref_count) = record.ref_counter.0.compare_exchange(
|
||||
0,
|
||||
-1,
|
||||
atomic::Ordering::Acquire,
|
||||
atomic::Ordering::Relaxed,
|
||||
) {
|
||||
match ref_count.cmp(&0) {
|
||||
Ordering::Less => {
|
||||
return Err(MultiBorrowError::MutablyBorrowed(handle));
|
||||
}
|
||||
Ordering::Greater => {
|
||||
return Err(MultiBorrowError::ImmutablyBorrowed(handle));
|
||||
}
|
||||
_ => (),
|
||||
// The record must be non-borrowed to be freed.
|
||||
// SAFETY: It is safe to access the counter because of borrow checker guarantees that
|
||||
// the record is alive.
|
||||
let current_ref_count = unsafe { record.ref_counter.get() };
|
||||
match current_ref_count.cmp(&0) {
|
||||
Ordering::Less => {
|
||||
return Err(MultiBorrowError::MutablyBorrowed(handle));
|
||||
}
|
||||
Ordering::Greater => {
|
||||
return Err(MultiBorrowError::ImmutablyBorrowed(handle));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
// SAFETY: We've enforced borrowing rules by the previous check.
|
||||
@@ -391,8 +377,6 @@ where
|
||||
|
||||
self.free_indices.borrow_mut().push(handle.index);
|
||||
|
||||
record.ref_counter.increment();
|
||||
|
||||
Ok(payload)
|
||||
}
|
||||
}
|
||||
@@ -439,7 +423,6 @@ where
|
||||
mod test {
|
||||
use super::MultiBorrowError;
|
||||
use crate::pool::Pool;
|
||||
use std::sync::atomic;
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
struct MyPayload(u32);
|
||||
@@ -485,25 +468,9 @@ mod test {
|
||||
// Test immutable borrowing of the same element with the following mutable borrowing.
|
||||
{
|
||||
let ref_a_1 = ctx.try_get(a);
|
||||
assert_eq!(
|
||||
ref_a_1
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.ref_counter
|
||||
.0
|
||||
.load(atomic::Ordering::Relaxed),
|
||||
1
|
||||
);
|
||||
assert_eq!(unsafe { ref_a_1.as_ref().unwrap().ref_counter.get() }, 1);
|
||||
let ref_a_2 = ctx.try_get(a);
|
||||
assert_eq!(
|
||||
ref_a_2
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.ref_counter
|
||||
.0
|
||||
.load(atomic::Ordering::Relaxed),
|
||||
2
|
||||
);
|
||||
assert_eq!(unsafe { ref_a_2.as_ref().unwrap().ref_counter.get() }, 2);
|
||||
|
||||
assert_eq!(ref_a_1.as_deref(), Ok(&val_a));
|
||||
assert_eq!(ref_a_2.as_deref(), Ok(&val_a));
|
||||
@@ -519,12 +486,7 @@ mod test {
|
||||
assert_eq!(mut_ref_a_1.as_deref_mut(), Ok(&mut val_a));
|
||||
|
||||
assert_eq!(
|
||||
mut_ref_a_1
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.ref_counter
|
||||
.0
|
||||
.load(atomic::Ordering::Relaxed),
|
||||
unsafe { mut_ref_a_1.as_ref().unwrap().ref_counter.get() },
|
||||
-1
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-dylib"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
authors = ["Dmitry Stepanov <[email protected]>", "Fyrox Engine Contributors"]
|
||||
license = "MIT"
|
||||
@@ -21,4 +21,4 @@ crate-type = ["dylib"]
|
||||
mesh_analysis = ["fyrox-impl/mesh_analysis"]
|
||||
|
||||
[dependencies]
|
||||
fyrox-impl = { path = "../fyrox-impl", version = "0.36.0" }
|
||||
fyrox-impl = { path = "../fyrox-impl", version = "0.36.2" }
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-graph"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -14,6 +14,6 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.2" }
|
||||
fxhash = "0.2.1"
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-graphics"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Graphics API abstraction for Fyrox Game Engine"
|
||||
@@ -13,7 +13,7 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0", features = ["serde"] }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2", features = ["serde"] }
|
||||
glow = "0.16"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
strum = "0.26.1"
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-impl"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>", "Fyrox Engine Contributors"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -15,15 +15,15 @@ readme = "README.md"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core-derive = { path = "../fyrox-core-derive", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0", features = ["serde"] }
|
||||
fyrox-sound = { path = "../fyrox-sound", version = "0.36.0" }
|
||||
fyrox-ui = { path = "../fyrox-ui", version = "0.36.0" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.0" }
|
||||
fyrox-animation = { path = "../fyrox-animation", version = "0.36.0" }
|
||||
fyrox-graph = { path = "../fyrox-graph", version = "0.36.0" }
|
||||
fyrox-graphics = { path = "../fyrox-graphics", version = "0.36.0" }
|
||||
fyrox-texture = { path = "../fyrox-texture", version = "0.36.0" }
|
||||
fyrox-core-derive = { path = "../fyrox-core-derive", version = "0.36.2" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2", features = ["serde"] }
|
||||
fyrox-sound = { path = "../fyrox-sound", version = "0.36.2" }
|
||||
fyrox-ui = { path = "../fyrox-ui", version = "0.36.2" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.2" }
|
||||
fyrox-animation = { path = "../fyrox-animation", version = "0.36.2" }
|
||||
fyrox-graph = { path = "../fyrox-graph", version = "0.36.2" }
|
||||
fyrox-graphics = { path = "../fyrox-graphics", version = "0.36.2" }
|
||||
fyrox-texture = { path = "../fyrox-texture", version = "0.36.2" }
|
||||
fyrox-autotile = { path = "../fyrox-autotile", version = "0.36.0" }
|
||||
rapier2d = { version = "0.23", features = ["debug-render"] }
|
||||
rapier3d = { version = "0.23", features = ["debug-render"] }
|
||||
|
||||
@@ -625,6 +625,8 @@ impl PhysicsWorld {
|
||||
max_ccd_substeps: self.integration_parameters.max_ccd_substeps as usize,
|
||||
};
|
||||
|
||||
let mut query = self.query.borrow_mut();
|
||||
|
||||
self.pipeline.step(
|
||||
&self.gravity,
|
||||
&integration_parameters,
|
||||
@@ -636,9 +638,7 @@ impl PhysicsWorld {
|
||||
&mut self.joints.set,
|
||||
&mut self.multibody_joints.set,
|
||||
&mut self.ccd_solver,
|
||||
// In Rapier 0.17 passing query pipeline here sometimes causing panic in numeric overflow,
|
||||
// so we keep updating it manually.
|
||||
None,
|
||||
Some(&mut query),
|
||||
&(),
|
||||
&*self.event_handler,
|
||||
);
|
||||
@@ -715,14 +715,7 @@ impl PhysicsWorld {
|
||||
pub fn cast_ray<S: QueryResultsStorage>(&self, opts: RayCastOptions, query_buffer: &mut S) {
|
||||
let time = instant::Instant::now();
|
||||
|
||||
let mut query = self.query.borrow_mut();
|
||||
|
||||
// TODO: Ideally this must be called once per frame, but it seems to be impossible because
|
||||
// a body can be deleted during the consecutive calls of this method which will most
|
||||
// likely end up in panic because of invalid handle stored in internal acceleration
|
||||
// structure. This could be fixed by delaying deleting of bodies/collider to the end
|
||||
// of the frame.
|
||||
query.update(&self.colliders);
|
||||
let query = self.query.borrow_mut();
|
||||
|
||||
query_buffer.clear();
|
||||
let ray = Ray::new(
|
||||
|
||||
@@ -1162,6 +1162,8 @@ impl PhysicsWorld {
|
||||
max_ccd_substeps: self.integration_parameters.max_ccd_substeps as usize,
|
||||
};
|
||||
|
||||
let mut query = self.query.borrow_mut();
|
||||
|
||||
self.pipeline.step(
|
||||
&self.gravity,
|
||||
&integration_parameters,
|
||||
@@ -1173,9 +1175,7 @@ impl PhysicsWorld {
|
||||
&mut self.joints.set,
|
||||
&mut self.multibody_joints.set,
|
||||
&mut self.ccd_solver,
|
||||
// In Rapier 0.17 passing query pipeline here sometimes causing panic in numeric overflow,
|
||||
// so we keep updating it manually.
|
||||
None,
|
||||
Some(&mut query),
|
||||
&(),
|
||||
&*self.event_handler,
|
||||
);
|
||||
@@ -1252,14 +1252,7 @@ impl PhysicsWorld {
|
||||
pub fn cast_ray<S: QueryResultsStorage>(&self, opts: RayCastOptions, query_buffer: &mut S) {
|
||||
let time = instant::Instant::now();
|
||||
|
||||
let mut query = self.query.borrow_mut();
|
||||
|
||||
// TODO: Ideally this must be called once per frame, but it seems to be impossible because
|
||||
// a body can be deleted during the consecutive calls of this method which will most
|
||||
// likely end up in panic because of invalid handle stored in internal acceleration
|
||||
// structure. This could be fixed by delaying deleting of bodies/collider to the end
|
||||
// of the frame.
|
||||
query.update(&self.colliders);
|
||||
let query = self.query.borrow_mut();
|
||||
|
||||
query_buffer.clear();
|
||||
let ray = Ray::new(
|
||||
|
||||
@@ -643,13 +643,11 @@ impl NodeTrait for Mesh {
|
||||
|
||||
fn on_global_transform_changed(
|
||||
&self,
|
||||
_new_global_transform: &Matrix4<f32>,
|
||||
new_global_transform: &Matrix4<f32>,
|
||||
context: &mut SyncContext,
|
||||
) {
|
||||
if self.surfaces.iter().any(|s| !s.bones.is_empty()) {
|
||||
let mut world_aabb = self
|
||||
.local_bounding_box()
|
||||
.transform(&self.global_transform());
|
||||
let mut world_aabb = self.local_bounding_box().transform(new_global_transform);
|
||||
|
||||
// Special case for skinned meshes.
|
||||
for surface in self.surfaces.iter() {
|
||||
@@ -662,10 +660,8 @@ impl NodeTrait for Mesh {
|
||||
|
||||
self.world_bounding_box.set(world_aabb)
|
||||
} else {
|
||||
self.world_bounding_box.set(
|
||||
self.local_bounding_box()
|
||||
.transform(&self.global_transform()),
|
||||
);
|
||||
self.world_bounding_box
|
||||
.set(self.local_bounding_box().transform(new_global_transform));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,20 +29,7 @@ use crate::{
|
||||
visitor::{Visit, VisitError, VisitResult, Visitor},
|
||||
},
|
||||
engine::SerializationContext,
|
||||
scene::{
|
||||
self,
|
||||
camera::Camera,
|
||||
decal::Decal,
|
||||
dim2::{self, rectangle::Rectangle},
|
||||
light::{directional::DirectionalLight, point::PointLight, spot::SpotLight},
|
||||
mesh::Mesh,
|
||||
node::Node,
|
||||
particle_system::ParticleSystem,
|
||||
pivot::Pivot,
|
||||
sound::{listener::Listener, Sound},
|
||||
sprite::Sprite,
|
||||
terrain::Terrain,
|
||||
},
|
||||
scene::node::Node,
|
||||
};
|
||||
|
||||
/// A wrapper for node pool record that allows to define custom visit method to have full
|
||||
@@ -51,80 +38,22 @@ use crate::{
|
||||
pub struct NodeContainer(Option<Node>);
|
||||
|
||||
fn read_node(name: &str, visitor: &mut Visitor) -> Result<Node, VisitError> {
|
||||
let node = {
|
||||
// Handle legacy nodes.
|
||||
let mut kind_id = 0u8;
|
||||
if kind_id.visit("KindId", visitor).is_ok() {
|
||||
let mut node = match kind_id {
|
||||
0 => Node::new(Pivot::default()),
|
||||
1 => {
|
||||
let mut region = visitor.enter_region(name)?;
|
||||
let mut region = visitor.enter_region(name)?;
|
||||
|
||||
let mut light_id = 0u32;
|
||||
light_id.visit("KindId", &mut region)?;
|
||||
let mut id = Uuid::default();
|
||||
id.visit("TypeUuid", &mut region)?;
|
||||
|
||||
let mut light_node = match light_id {
|
||||
0 => Node::new(SpotLight::default()),
|
||||
1 => Node::new(PointLight::default()),
|
||||
2 => Node::new(DirectionalLight::default()),
|
||||
_ => {
|
||||
return Err(VisitError::User(format!(
|
||||
"Invalid legacy light kind {light_id}"
|
||||
)))
|
||||
}
|
||||
};
|
||||
let serialization_context = region
|
||||
.blackboard
|
||||
.get::<SerializationContext>()
|
||||
.expect("Visitor environment must contain serialization context!");
|
||||
|
||||
light_node.visit("Data", &mut region)?;
|
||||
let mut node = serialization_context
|
||||
.node_constructors
|
||||
.try_create(&id)
|
||||
.ok_or_else(|| VisitError::User(format!("Unknown node type uuid {id}!")))?;
|
||||
|
||||
return Ok(light_node);
|
||||
}
|
||||
2 => Node::new(Camera::default()),
|
||||
3 => Node::new(Mesh::default()),
|
||||
4 => Node::new(Sprite::default()),
|
||||
5 => Node::new(ParticleSystem::default()),
|
||||
6 => Node::new(Terrain::default()),
|
||||
7 => Node::new(Decal::default()),
|
||||
8 => Node::new(scene::rigidbody::RigidBody::default()),
|
||||
9 => Node::new(scene::collider::Collider::default()),
|
||||
10 => Node::new(scene::joint::Joint::default()),
|
||||
11 => Node::new(Rectangle::default()),
|
||||
12 => Node::new(dim2::rigidbody::RigidBody::default()),
|
||||
13 => Node::new(dim2::collider::Collider::default()),
|
||||
14 => Node::new(dim2::joint::Joint::default()),
|
||||
15 => Node::new(Sound::default()),
|
||||
16 => Node::new(Listener::default()),
|
||||
_ => {
|
||||
return Err(VisitError::User(format!(
|
||||
"Invalid legacy node kind {kind_id}"
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
||||
node.visit(name, visitor)?;
|
||||
|
||||
node
|
||||
} else {
|
||||
// Latest version
|
||||
let mut region = visitor.enter_region(name)?;
|
||||
|
||||
let mut id = Uuid::default();
|
||||
id.visit("TypeUuid", &mut region)?;
|
||||
|
||||
let serialization_context = region
|
||||
.blackboard
|
||||
.get::<SerializationContext>()
|
||||
.expect("Visitor environment must contain serialization context!");
|
||||
|
||||
let mut node = serialization_context
|
||||
.node_constructors
|
||||
.try_create(&id)
|
||||
.ok_or_else(|| VisitError::User(format!("Unknown node type uuid {id}!")))?;
|
||||
|
||||
node.visit("NodeData", &mut region)?;
|
||||
|
||||
node
|
||||
}
|
||||
};
|
||||
node.visit("NodeData", &mut region)?;
|
||||
|
||||
Ok(node)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-math"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
@@ -620,6 +620,15 @@ pub struct SmoothAngle {
|
||||
}
|
||||
|
||||
impl SmoothAngle {
|
||||
#[inline]
|
||||
pub fn new(angle: f32, speed: f32) -> Self {
|
||||
Self {
|
||||
angle,
|
||||
target: angle,
|
||||
speed,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_target(&mut self, angle: f32) -> &mut Self {
|
||||
self.target = angle;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-resource"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -14,7 +14,7 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2" }
|
||||
fxhash = "0.2.1"
|
||||
ron = "0.8.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-scripts"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -14,4 +14,4 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox = { version = "0.36.0", path = "../fyrox" }
|
||||
fyrox = { version = "0.36.2", path = "../fyrox" }
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-sound"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -15,8 +15,8 @@ readme = "README.md"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.2" }
|
||||
hrtf = "0.8.0"
|
||||
hound = "3.4.0"
|
||||
strum = "0.26.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-texture"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Texture utilities for Fyrox Engine"
|
||||
@@ -13,8 +13,8 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2" }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.2" }
|
||||
ddsfile = "0.5.0"
|
||||
fast_image_resize = "5.0.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-ui"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -15,11 +15,11 @@ readme = "README.md"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.0", features = ["serde"] }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.0" }
|
||||
fyrox-texture = { path = "../fyrox-texture", version = "0.36.0" }
|
||||
fyrox-graph = { path = "../fyrox-graph", version = "0.36.0" }
|
||||
fyrox-animation = { path = "../fyrox-animation", version = "0.36.0" }
|
||||
fyrox-core = { path = "../fyrox-core", version = "0.36.2", features = ["serde"] }
|
||||
fyrox-resource = { path = "../fyrox-resource", version = "0.36.2" }
|
||||
fyrox-texture = { path = "../fyrox-texture", version = "0.36.2" }
|
||||
fyrox-graph = { path = "../fyrox-graph", version = "0.36.2" }
|
||||
fyrox-animation = { path = "../fyrox-animation", version = "0.36.2" }
|
||||
lazy_static = "1.4.0"
|
||||
copypasta = "0.10.1"
|
||||
fontdue = "0.9.2"
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
authors = ["Dmitry Stepanov <[email protected]>", "Fyrox Engine Contributors"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
@@ -20,5 +20,5 @@ dylib = ["fyrox-dylib"]
|
||||
mesh_analysis = ["fyrox-impl/mesh_analysis", "fyrox-dylib/mesh_analysis"]
|
||||
|
||||
[dependencies]
|
||||
fyrox-impl = { version = "0.36.0", path = "../fyrox-impl", optional = true }
|
||||
fyrox-dylib = { version = "0.36.0", path = "../fyrox-dylib", optional = true }
|
||||
fyrox-impl = { version = "0.36.2", path = "../fyrox-impl", optional = true }
|
||||
fyrox-dylib = { version = "0.36.2", path = "../fyrox-dylib", optional = true }
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-project-manager"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
license = "MIT"
|
||||
@@ -13,9 +13,9 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox = { version = "0.36.0", path = "../fyrox" }
|
||||
fyrox-template-core = { version = "0.36.0", path = "../template-core" }
|
||||
fyrox-build-tools = { version = "0.36.0", path = "../fyrox-build-tools" }
|
||||
fyrox = { version = "0.36.2", path = "../fyrox" }
|
||||
fyrox-template-core = { version = "0.36.2", path = "../template-core" }
|
||||
fyrox-build-tools = { version = "0.36.2", path = "../fyrox-build-tools" }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
ron = "0.8.1"
|
||||
open = "5.0.1"
|
||||
|
||||
@@ -191,10 +191,32 @@ fn make_project_item(
|
||||
.with_text(engine_version)
|
||||
.build(ctx);
|
||||
|
||||
let project_size = if let Some(project_dir) = Path::new(path).parent() {
|
||||
let size = utils::calculate_directory_size(project_dir);
|
||||
utils::format_size(size)
|
||||
} else {
|
||||
String::from("N/A")
|
||||
};
|
||||
|
||||
let size_text = TextBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
.with_foreground(ctx.style.property(Style::BRUSH_BRIGHTEST))
|
||||
.with_margin(Thickness {
|
||||
left: 0.0,
|
||||
top: 6.0,
|
||||
right: 8.0,
|
||||
bottom: 0.0,
|
||||
}),
|
||||
)
|
||||
.with_font_size(13.0.into())
|
||||
.with_text(format!("Size: {}", project_size))
|
||||
.build(ctx);
|
||||
|
||||
let info = StackPanelBuilder::new(
|
||||
WidgetBuilder::new()
|
||||
.with_horizontal_alignment(HorizontalAlignment::Right)
|
||||
.with_vertical_alignment(VerticalAlignment::Center)
|
||||
.with_child(size_text)
|
||||
.with_child(engine_version)
|
||||
.with_child(hot_reload),
|
||||
)
|
||||
|
||||
@@ -226,8 +226,9 @@ impl UpgradeTool {
|
||||
if message.destination() == self.version_type_selector {
|
||||
match *index {
|
||||
0 => {
|
||||
self.selected_version =
|
||||
Version::Specific(fyrox_template_core::CURRENT_VERSION.to_string());
|
||||
self.selected_version = Version::Specific(
|
||||
fyrox_template_core::CURRENT_ENGINE_VERSION.to_string(),
|
||||
);
|
||||
}
|
||||
1 => {
|
||||
self.selected_version = Version::Local;
|
||||
|
||||
@@ -28,6 +28,7 @@ use fyrox::{
|
||||
},
|
||||
};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
@@ -157,3 +158,38 @@ pub fn fyrox_dependency_from_path(manifest_path: &Path) -> Option<Dependency> {
|
||||
pub fn has_fyrox_in_deps(metadata: &Metadata) -> bool {
|
||||
fyrox_dependency(metadata).is_some()
|
||||
}
|
||||
|
||||
pub fn calculate_directory_size(path: &Path) -> u64 {
|
||||
let mut total_size = 0;
|
||||
|
||||
if let Ok(entries) = fs::read_dir(path) {
|
||||
for entry in entries.flatten() {
|
||||
let entry_path = entry.path();
|
||||
if entry_path.is_file() {
|
||||
if let Ok(metadata) = entry.metadata() {
|
||||
total_size += metadata.len();
|
||||
}
|
||||
} else if entry_path.is_dir() {
|
||||
total_size += calculate_directory_size(&entry_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total_size
|
||||
}
|
||||
|
||||
pub fn format_size(size: u64) -> String {
|
||||
const KB: u64 = 1024;
|
||||
const MB: u64 = KB * 1024;
|
||||
const GB: u64 = MB * 1024;
|
||||
|
||||
if size >= GB {
|
||||
format!("{:.2} GB", size as f64 / GB as f64)
|
||||
} else if size >= MB {
|
||||
format!("{:.2} MB", size as f64 / MB as f64)
|
||||
} else if size >= KB {
|
||||
format!("{:.2} KB", size as f64 / KB as f64)
|
||||
} else {
|
||||
format!("{} B", size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[package]
|
||||
name = "fyrox-template-core"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
license = "MIT"
|
||||
description = "Project template generator for Fyrox engine"
|
||||
keywords = ["fyrox", "game", "project"]
|
||||
categories = ["game-development"]
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md", "engine.version", "editor.version", "scripts.version"]
|
||||
homepage = "https://fyrox.rs"
|
||||
repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
readme = "README.md"
|
||||
@@ -19,4 +19,7 @@ convert_case = "0.6.0"
|
||||
toml = "0.8.10"
|
||||
toml_edit = "0.22.6"
|
||||
regex = "1.7.3"
|
||||
unicode-xid = "0.2.6"
|
||||
unicode-xid = "0.2.6"
|
||||
|
||||
[build-dependencies]
|
||||
toml_edit = "0.22.6"
|
||||
@@ -0,0 +1,36 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
};
|
||||
use toml_edit::DocumentMut;
|
||||
|
||||
fn write_version_file(src: &str, dest: &str) {
|
||||
let mut fyrox_toml = File::open(src).expect("Cargo.toml must exist!");
|
||||
|
||||
let mut toml = String::new();
|
||||
fyrox_toml
|
||||
.read_to_string(&mut toml)
|
||||
.expect("File must be readable");
|
||||
|
||||
let document = toml.parse::<DocumentMut>().unwrap();
|
||||
|
||||
let package = document
|
||||
.get("package")
|
||||
.and_then(|i| i.as_table())
|
||||
.expect("package section must exist!");
|
||||
|
||||
let version = package.get("version").expect("version must be set!");
|
||||
|
||||
let mut file = File::create(dest).expect("version file must be accessible for writing!");
|
||||
|
||||
let version = version.to_string().replace('\"', "");
|
||||
file.write_all(version.as_bytes())
|
||||
.expect("fyrox.version must be writable!");
|
||||
drop(file);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
write_version_file("../fyrox/Cargo.toml", "./engine.version");
|
||||
write_version_file("../editor/Cargo.toml", "./editor.version");
|
||||
write_version_file("../fyrox-scripts/Cargo.toml", "./scripts.version");
|
||||
}
|
||||
+13
-29
@@ -26,32 +26,16 @@ use std::{
|
||||
collections::HashMap,
|
||||
fmt::Display,
|
||||
fs::{create_dir_all, read_dir, remove_dir_all, File},
|
||||
io::{Cursor, Read, Write},
|
||||
io::{Read, Write},
|
||||
path::Path,
|
||||
process::Command,
|
||||
sync::LazyLock,
|
||||
};
|
||||
use toml_edit::{table, value, DocumentMut};
|
||||
use uuid::Uuid;
|
||||
|
||||
// Template generator version must match the engine version. This is checked by the CI.
|
||||
pub static CURRENT_VERSION: LazyLock<String> = LazyLock::new(|| {
|
||||
let manifest = include_bytes!("../Cargo.toml");
|
||||
|
||||
let mut file = Cursor::new(&manifest);
|
||||
let mut toml = String::new();
|
||||
if file.read_to_string(&mut toml).is_ok() {
|
||||
if let Ok(document) = toml.parse::<DocumentMut>() {
|
||||
if let Some(package) = document.get("package").and_then(|i| i.as_table()) {
|
||||
if let Some(version) = package.get("version") {
|
||||
return version.to_string().replace('\"', "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panic!("Project manager's Cargo.toml is malformed!");
|
||||
});
|
||||
pub static CURRENT_ENGINE_VERSION: &str = include_str!("../engine.version");
|
||||
pub static CURRENT_EDITOR_VERSION: &str = include_str!("../editor.version");
|
||||
pub static CURRENT_SCRIPTS_VERSION: &str = include_str!("../scripts.version");
|
||||
|
||||
fn write_file<P: AsRef<Path>, S: AsRef<str>>(path: P, content: S) -> Result<(), String> {
|
||||
let mut file = File::create(path.as_ref()).map_err(|e| e.to_string())?;
|
||||
@@ -621,7 +605,6 @@ fn init_workspace(base_path: &Path, vcs: &str) -> Result<(), String> {
|
||||
}
|
||||
|
||||
// Write Cargo.toml
|
||||
let version = &*CURRENT_VERSION;
|
||||
write_file(
|
||||
base_path.join("Cargo.toml"),
|
||||
format!(
|
||||
@@ -631,10 +614,10 @@ members = ["editor", "executor", "executor-wasm", "executor-android", "game", "g
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies.fyrox]
|
||||
version = "{version}"
|
||||
version = "{CURRENT_ENGINE_VERSION}"
|
||||
default-features = false
|
||||
[workspace.dependencies.fyroxed_base]
|
||||
version = "{version}"
|
||||
version = "{CURRENT_EDITOR_VERSION}"
|
||||
default-features = false
|
||||
|
||||
# Separate build profiles for hot reloading. These profiles ensures that build artifacts for
|
||||
@@ -800,10 +783,10 @@ pub fn upgrade_project(root_path: &Path, version: &str, local: bool) -> Result<(
|
||||
// TODO: This will be obsolete in 1.0 and should be removed.
|
||||
let editor_versions = [
|
||||
(
|
||||
CURRENT_VERSION.to_string(),
|
||||
CURRENT_ENGINE_VERSION.to_string(),
|
||||
(
|
||||
CURRENT_VERSION.to_string(),
|
||||
Some(CURRENT_VERSION.to_string()),
|
||||
CURRENT_EDITOR_VERSION.to_string(),
|
||||
Some(CURRENT_SCRIPTS_VERSION.to_string()),
|
||||
),
|
||||
),
|
||||
(
|
||||
@@ -861,10 +844,11 @@ pub fn upgrade_project(root_path: &Path, version: &str, local: bool) -> Result<(
|
||||
dependencies["fyrox_scripts"] = scripts_table;
|
||||
}
|
||||
} else {
|
||||
dependencies["fyrox"] = value(&*CURRENT_VERSION);
|
||||
dependencies["fyroxed_base"] = value(&*CURRENT_VERSION);
|
||||
dependencies["fyrox"] = value(CURRENT_ENGINE_VERSION);
|
||||
dependencies["fyroxed_base"] = value(CURRENT_EDITOR_VERSION);
|
||||
if dependencies.contains_key("fyrox_scripts") {
|
||||
dependencies["fyrox_scripts"] = value(&*CURRENT_VERSION);
|
||||
dependencies["fyrox_scripts"] =
|
||||
value(CURRENT_SCRIPTS_VERSION);
|
||||
}
|
||||
}
|
||||
} else if version == "nightly" {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fyrox-template"
|
||||
version = "0.36.0"
|
||||
version = "0.36.2"
|
||||
edition = "2021"
|
||||
authors = ["Dmitry Stepanov <[email protected]>"]
|
||||
license = "MIT"
|
||||
@@ -14,5 +14,5 @@ readme = "README.md"
|
||||
rust-version = "1.80"
|
||||
|
||||
[dependencies]
|
||||
fyrox-template-core = { version = "0.36.0", path = "../template-core" }
|
||||
fyrox-template-core = { version = "0.36.2", path = "../template-core" }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
Reference in New Issue
Block a user