Skip to content

Commit

Permalink
added an ability to upgrade projects in project manager
Browse files Browse the repository at this point in the history
- minor fixes
  • Loading branch information
mrDIMAS committed Dec 9, 2024
1 parent bc9397e commit ef1d594
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 11 deletions.
3 changes: 1 addition & 2 deletions project-manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@

//! Project manager is used to create, import, rename, delete, run and edit projects built with Fyrox.
#![cfg_attr(target_os = "windows", windows_subsystem = "windows")]

mod build;
mod manager;
mod project;
mod settings;
mod upgrade;
mod utils;

use crate::{manager::ProjectManager, utils::make_button};
Expand Down
48 changes: 45 additions & 3 deletions project-manager/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{
build::BuildWindow,
project::ProjectWizard,
settings::{Project, Settings},
upgrade::UpgradeTool,
utils::{self, is_production_ready, load_image, make_button},
};
use fyrox::{
Expand Down Expand Up @@ -89,13 +90,16 @@ pub struct ProjectManager {
open_log: Handle<UiNode>,
message_count: Handle<UiNode>,
deletion_confirmation_dialog: Handle<UiNode>,
upgrade: Handle<UiNode>,
upgrade_tool: Option<UpgradeTool>,
}

fn make_project_item(
name: &str,
path: &Path,
hot_reload: bool,
visible: bool,
engine_version: &str,
ctx: &mut BuildContext,
) -> Handle<UiNode> {
let icon = ImageBuilder::new(
Expand Down Expand Up @@ -153,6 +157,17 @@ fn make_project_item(
.with_opt_texture(load_image(include_bytes!("../resources/flame.png")))
.build(ctx);

let engine_version = TextBuilder::new(
WidgetBuilder::new()
.on_row(0)
.on_column(2)
.with_vertical_alignment(VerticalAlignment::Bottom)
.with_horizontal_alignment(HorizontalAlignment::Right)
.with_margin(Thickness::uniform(3.0)),
)
.with_text(engine_version)
.build(ctx);

DecoratorBuilder::new(
BorderBuilder::new(
WidgetBuilder::new()
Expand All @@ -163,7 +178,8 @@ fn make_project_item(
WidgetBuilder::new()
.with_child(icon)
.with_child(item)
.with_child(hot_reload),
.with_child(hot_reload)
.with_child(engine_version),
)
.add_column(Column::auto())
.add_column(Column::stretch())
Expand Down Expand Up @@ -193,11 +209,17 @@ fn make_project_items(
.to_lowercase()
.contains(&search_text.to_lowercase());

let engine_version = utils::read_crate_metadata(&project.manifest_path)
.ok()
.and_then(|metadata| utils::fyrox_version(&metadata))
.unwrap_or_default();

make_project_item(
&project.name,
&project.manifest_path,
project.hot_reload,
visible,
&engine_version,
ctx,
)
})
Expand Down Expand Up @@ -323,11 +345,13 @@ impl ProjectManager {
let edit_tooltip = "Build the editor and run it.";
let run_tooltip = "Build the game and run it.";
let delete_tooltip = "Delete the entire project with all its assets. \
WARNING: This is irreversible operation and permanently deletes your project!";
WARNING: This is irreversible operation and it permanently deletes your project!";
let upgrade_tooltip = "Allows you to change the engine version in a few clicks.";

let edit = make_button("Edit", 130.0, 25.0, 3, 0, 0, Some(edit_tooltip), ctx);
let run = make_button("Run", 130.0, 25.0, 4, 0, 0, Some(run_tooltip), ctx);
let delete = make_button("Delete", 130.0, 25.0, 5, 0, 0, Some(delete_tooltip), ctx);
let upgrade = make_button("Upgrade", 130.0, 25.0, 6, 0, 0, Some(upgrade_tooltip), ctx);
let hot_reload = CheckBoxBuilder::new(
WidgetBuilder::new()
.with_margin(Thickness::uniform(1.0))
Expand All @@ -353,7 +377,8 @@ impl ProjectManager {
.with_child(hot_reload)
.with_child(edit)
.with_child(run)
.with_child(delete),
.with_child(delete)
.with_child(upgrade),
)
.build(ctx);

Expand Down Expand Up @@ -420,6 +445,8 @@ impl ProjectManager {
open_log,
message_count,
deletion_confirmation_dialog: Default::default(),
upgrade,
upgrade_tool: None,
}
}

Expand Down Expand Up @@ -573,6 +600,13 @@ impl ProjectManager {
let _ = open::that("https://rustup.rs/");
} else if button == self.open_log {
self.log.open(ui);
} else if button == self.upgrade {
if let Some(index) = self.selection {
if let Some(project) = self.settings.projects.get(index) {
let ctx = &mut ui.build_ctx();
self.upgrade_tool = Some(UpgradeTool::new(project, ctx));
}
}
}

if let Some(index) = self.selection {
Expand Down Expand Up @@ -643,6 +677,14 @@ impl ProjectManager {
build_window.handle_ui_message(message, ui);
}

if let Some(upgrade_tool) = self.upgrade_tool.take() {
if let Some(index) = self.selection {
if let Some(project) = self.settings.projects.get(index) {
self.upgrade_tool = upgrade_tool.handle_ui_message(message, ui, project);
}
}
}

if let Some(ButtonMessage::Click) = message.data() {
self.on_button_click(message.destination, ui);
} else if let Some(ListViewMessage::SelectionChanged(selection)) = message.data() {
Expand Down
156 changes: 156 additions & 0 deletions project-manager/src/upgrade.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use crate::{settings::Project, utils, utils::make_button};
use fyrox::{
core::{log::Log, pool::Handle},
gui::{
button::ButtonMessage,
dropdown_list::DropdownListBuilder,
grid::{Column, GridBuilder, Row},
message::{MessageDirection, UiMessage},
stack_panel::StackPanelBuilder,
text::TextBuilder,
utils::make_dropdown_list_option,
widget::WidgetBuilder,
window::{WindowBuilder, WindowMessage, WindowTitle},
BuildContext, HorizontalAlignment, Orientation, Thickness, UiNode, UserInterface,
},
};

#[allow(dead_code)]
pub struct UpgradeTool {
window: Handle<UiNode>,
version: Handle<UiNode>,
version_selector: Handle<UiNode>,
upgrade: Handle<UiNode>,
cancel: Handle<UiNode>,
}

impl UpgradeTool {
pub fn new(project: &Project, ctx: &mut BuildContext) -> Self {
let version = utils::fyrox_version_or_default(&project.manifest_path);

let version = TextBuilder::new(
WidgetBuilder::new()
.on_row(0)
.with_margin(Thickness::uniform(1.0)),
)
.with_text(format!("Current Engine Version: {version}"))
.build(ctx);

let version_selector = DropdownListBuilder::new(
WidgetBuilder::new()
.with_tab_index(Some(0))
.on_row(1)
.with_margin(Thickness::uniform(1.0)),
)
.with_items(vec![
make_dropdown_list_option(ctx, "Specific"),
make_dropdown_list_option(ctx, "Latest"),
make_dropdown_list_option(ctx, "Nightly"),
])
.with_selected(0)
.build(ctx);

let upgrade;
let cancel;
let buttons = StackPanelBuilder::new(
WidgetBuilder::new()
.with_horizontal_alignment(HorizontalAlignment::Right)
.on_row(3)
.with_child({
upgrade = make_button("Upgrade", 130.0, 25.0, 1, 0, 0, None, ctx);
upgrade
})
.with_child({
cancel = make_button("Cancel", 130.0, 25.0, 2, 0, 0, None, ctx);
cancel
}),
)
.with_orientation(Orientation::Horizontal)
.build(ctx);

let content = GridBuilder::new(
WidgetBuilder::new()
.with_child(version)
.with_child(version_selector)
.with_child(buttons),
)
.add_column(Column::stretch())
.add_row(Row::auto())
.add_row(Row::auto())
.add_row(Row::stretch())
.add_row(Row::auto())
.build(ctx);

let window = WindowBuilder::new(WidgetBuilder::new().with_width(300.0).with_height(200.0))
.open(false)
.with_title(WindowTitle::text("Upgrade Project"))
.with_content(content)
.with_remove_on_close(true)
.build(ctx);

ctx.sender()
.send(WindowMessage::open_modal(
window,
MessageDirection::ToWidget,
true,
true,
))
.unwrap();

Self {
window,
version,
version_selector,
upgrade,
cancel,
}
}

pub fn handle_ui_message(
self,
message: &UiMessage,
ui: &mut UserInterface,
project: &Project,
) -> Option<Self> {
if let Some(ButtonMessage::Click) = message.data() {
if message.destination() == self.upgrade {
Log::verify(fyrox_template_core::upgrade_project(
&project.manifest_path,
"",
false,
));
} else if message.destination() == self.cancel {
ui.send_message(WindowMessage::close(
self.window,
MessageDirection::ToWidget,
));
}
} else if let Some(WindowMessage::Close) = message.data() {
if message.destination() == self.window {
return None;
}
}

Some(self)
}
}
31 changes: 25 additions & 6 deletions project-manager/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ pub fn folder_to_manifest_path(path: &Path) -> PathBuf {
pub fn read_crate_metadata(manifest_path: &Path) -> Result<Metadata, String> {
match Command::new("cargo")
.arg("metadata")
.arg("--no-deps")
.arg("--format-version")
.arg("1")
.arg("--manifest-path")
.arg(manifest_path)
.stdout(Stdio::piped())
Expand All @@ -151,11 +154,27 @@ pub fn read_crate_metadata(manifest_path: &Path) -> Result<Metadata, String> {
}
}

pub fn fyrox_version(metadata: &Metadata) -> Option<String> {
for package in metadata.packages.iter() {
for dependency in package.dependencies.iter() {
if dependency.name == "fyrox" {
let version = dependency.req.to_string();
let pretty_version = version.replace('^', "");
let pretty_version = pretty_version.replace('+', "");
return Some(pretty_version);
}
}
}
None
}

pub fn fyrox_version_or_default(manifest_path: &Path) -> String {
read_crate_metadata(manifest_path)
.ok()
.and_then(|metadata| fyrox_version(&metadata))
.unwrap_or_default()
}

pub fn has_fyrox_in_deps(metadata: &Metadata) -> bool {
metadata.packages.iter().any(|package| {
package
.dependencies
.iter()
.any(|dependency| dependency.name == "fyrox")
})
fyrox_version(metadata).is_some()
}

0 comments on commit ef1d594

Please sign in to comment.