From 41aaf0fe694c58d36c44c0eb3a899310f68e0809 Mon Sep 17 00:00:00 2001 From: Samuel Selleck Date: Mon, 30 Sep 2024 12:19:00 -0700 Subject: [PATCH] get time millis through engine --- pax-chassis-web/Cargo.toml | 1 + pax-chassis-web/src/lib.rs | 14 ++++++++---- pax-designer/src/glass/mod.pax | 1 - pax-designer/src/glass/mod.rs | 20 ++++++++++++---- pax-designer/src/model/action/pointer.rs | 29 +++++++++++++++++------- pax-runtime-api/src/lib.rs | 3 +++ pax-runtime/src/api.rs | 11 ++++++++- pax-runtime/src/engine/expanded_node.rs | 2 ++ pax-runtime/src/engine/mod.rs | 6 +++++ 9 files changed, 68 insertions(+), 19 deletions(-) diff --git a/pax-chassis-web/Cargo.toml b/pax-chassis-web/Cargo.toml index b0e7d0ea4..ad8e8d072 100644 --- a/pax-chassis-web/Cargo.toml +++ b/pax-chassis-web/Cargo.toml @@ -32,6 +32,7 @@ console_log = "1.0.0" log = "0.4.20" console_error_panic_hook = { version = "0.1.6", optional = true } js-sys = "0.3.63" +web-time = "1.1.0" [dependencies.web-sys] version = "0.3.10" diff --git a/pax-chassis-web/src/lib.rs b/pax-chassis-web/src/lib.rs index ef603500e..9c30589ba 100644 --- a/pax-chassis-web/src/lib.rs +++ b/pax-chassis-web/src/lib.rs @@ -15,6 +15,8 @@ use pax_runtime::DefinitionToInstanceTraverser; use pax_runtime_api::borrow_mut; use pax_runtime_api::Event; use pax_runtime_api::Focus; +use web_time::Duration; +use web_time::Instant; use_RefCell!(); use std::rc::Rc; @@ -75,7 +77,7 @@ impl PaxChassisWeb { userland_definition_to_instance_traverser: Box, designer_definition_to_instance_traverser: Box, ) -> Self { - let (width, height, os_info) = Self::init_common(); + let (width, height, os_info, get_ellapsed_millis) = Self::init_common(); let query_string = window() .unwrap() .location() @@ -97,6 +99,7 @@ impl PaxChassisWeb { designtime_manager.clone(), Platform::Web, os_info, + get_ellapsed_millis, ); let engine_container: Rc> = Rc::new(RefCell::new(engine)); Self { @@ -112,7 +115,7 @@ impl PaxChassisWeb { pub async fn new( definition_to_instance_traverser: Box, ) -> Self { - let (width, height, os_info) = Self::init_common(); + let (width, height, os_info, get_time) = Self::init_common(); let main_component_instance = definition_to_instance_traverser.get_main_component(USERLAND_COMPONENT_ROOT); @@ -121,6 +124,7 @@ impl PaxChassisWeb { (width, height), Platform::Web, os_info, + get_time, ); let engine_container: Rc> = Rc::new(RefCell::new(engine)); @@ -131,7 +135,7 @@ impl PaxChassisWeb { } } - fn init_common() -> (f64, f64, OS) { + fn init_common() -> (f64, f64, OS, Box u128>) { let window = window().unwrap(); let user_agent_str = window.navigator().user_agent().ok(); let os_info = user_agent_str @@ -140,7 +144,9 @@ impl PaxChassisWeb { let width = window.inner_width().unwrap().as_f64().unwrap(); let height = window.inner_height().unwrap().as_f64().unwrap(); - (width, height, os_info) + let start = Instant::now(); + let get_time = Box::new(move || start.elapsed().as_millis()); + (width, height, os_info, get_time) } } diff --git a/pax-designer/src/glass/mod.pax b/pax-designer/src/glass/mod.pax index 9aa6f93fa..f7a166818 100644 --- a/pax-designer/src/glass/mod.pax +++ b/pax-designer/src/glass/mod.pax @@ -62,7 +62,6 @@ @settings { @mount: on_mount, @tick: on_pre_render, - @double_click: handle_double_click @context_menu: self.context_menu #project { diff --git a/pax-designer/src/glass/mod.rs b/pax-designer/src/glass/mod.rs index 740f0562a..49b663452 100644 --- a/pax-designer/src/glass/mod.rs +++ b/pax-designer/src/glass/mod.rs @@ -1,3 +1,6 @@ +use std::rc::Rc; +use std::time::Instant; + use anyhow::anyhow; use pax_engine::api::Fill; use pax_engine::api::*; @@ -45,6 +48,8 @@ pub struct Glass { pub on_tool_change: Property, // used to make scroller containers open if manifest version changed pub scroller_manifest_version_listener: Property, + // TODO this needs to track real time, not frame count, eventually + pub time_last_click: Property, } impl Glass { @@ -114,11 +119,9 @@ impl Glass { args.prevent_default(); } - pub fn handle_double_click(&mut self, ctx: &NodeContext, event: Event) { - // if a ControlPoint was double clicked, don't handle glass double click - if event.cancelled() { - return; - } + // NOTE: This is NOT triggered by engine - we are handling our own double click behavior + // by checking time in self.handle_mouse_down + pub fn handle_double_click(&mut self, ctx: &NodeContext, event: &Event) { // TODO move to another file (need to figure out structure) let info = model::read_app_state(|app_state| { let selected_nodes = app_state.selected_template_node_ids.get(); @@ -193,6 +196,13 @@ impl Glass { } pub fn handle_mouse_down(&mut self, ctx: &NodeContext, args: Event) { + let last_time = self.time_last_click.get(); + let curr_time = ctx.ellapsed_time_millis() as u64; + if (curr_time - last_time) < 500 { + self.handle_double_click(ctx, &args); + } + self.time_last_click.set(curr_time); + let prevent_default = || args.prevent_default(); model::perform_action( &crate::model::action::pointer::MouseEntryPointAction { diff --git a/pax-designer/src/model/action/pointer.rs b/pax-designer/src/model/action/pointer.rs index e072794cc..a54708f1d 100644 --- a/pax-designer/src/model/action/pointer.rs +++ b/pax-designer/src/model/action/pointer.rs @@ -243,17 +243,30 @@ impl Action for MouseEntryPointAction<'_> { match res { std::ops::ControlFlow::Continue(_) => false, std::ops::ControlFlow::Break(_) => { - // TODO this could most likely be done in a nicer way: - // make a tool "stack", and return to last tool here instead if let Err(e) = tool.finish(ctx) { log::warn!("finishing tool failed: {e}"); }; - ctx.app_state - .selected_tool - .set(match ctx.app_state.unit_mode.get() { - SizeUnit::Pixels => Tool::PointerPixels, - SizeUnit::Percent => Tool::PointerPercent, - }); + // TODO this could most likely be done in a nicer way: + // make a tool "stack", and return to last tool here + // instead. How to handle ToolBehavior vs Toolbar state + // if doing this? (needs to be synced). Associate each + // ToolBehavior with a Tool in toolbar? + // TODO might want to make a toolbar click immediately + // activate a tool, and then make the tool itself handle + // mousedown. (would allow for easier way for tool + // settings view to show on tool selection) + match ctx.app_state.selected_tool.get() { + Tool::Paintbrush => (), + _ => { + ctx.app_state.selected_tool.set( + match ctx.app_state.unit_mode.get() { + SizeUnit::Pixels => Tool::PointerPixels, + SizeUnit::Percent => Tool::PointerPercent, + }, + ); + } + } + true } } diff --git a/pax-runtime-api/src/lib.rs b/pax-runtime-api/src/lib.rs index f2d6520ca..113672b16 100644 --- a/pax-runtime-api/src/lib.rs +++ b/pax-runtime-api/src/lib.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet, VecDeque}; use std::fmt::Display; use std::ops::{Add, Deref, Mul, Neg, Sub}; +use std::time::Instant; use crate::math::Space; use kurbo::BezPath; @@ -916,6 +917,8 @@ impl Interpolatable for Vec { } } +impl Interpolatable for Instant {} + impl Interpolatable for char {} impl Interpolatable for f64 { diff --git a/pax-runtime/src/api.rs b/pax-runtime/src/api.rs index 8a97e36cd..cc2d3e2b3 100644 --- a/pax-runtime/src/api.rs +++ b/pax-runtime/src/api.rs @@ -1,4 +1,7 @@ -use std::rc::{Rc, Weak}; +use std::{ + rc::{Rc, Weak}, + time::Instant, +}; use_RefCell!(); use crate::{ @@ -42,6 +45,7 @@ pub struct NodeContext { #[cfg(feature = "designtime")] pub designtime: Rc>, + pub(crate) get_ellapsed_millis: Rc u128>, } impl NodeContext { @@ -57,6 +61,11 @@ impl NodeContext { self.node_transform_and_bounds.as_transform().inverse() * p } + /// Get std::time::Instant::now() + pub fn ellapsed_time_millis(&self) -> u128 { + (self.get_ellapsed_millis)() + } + pub fn navigate_to(&self, url: &str, target: NavigationTarget) { self.runtime_context .enqueue_native_message(NativeMessage::Navigate(NavigationPatch { diff --git a/pax-runtime/src/engine/expanded_node.rs b/pax-runtime/src/engine/expanded_node.rs index 7c2d3d941..56790ca9f 100644 --- a/pax-runtime/src/engine/expanded_node.rs +++ b/pax-runtime/src/engine/expanded_node.rs @@ -264,6 +264,7 @@ impl ExpandedNode { _context: &Rc, ) { *borrow_mut!(self.instance_node) = Rc::clone(&template); + log::debug!("recreate"); (&template .base() .instance_prototypical_common_properties_factory)( @@ -634,6 +635,7 @@ impl ExpandedNode { runtime_context: ctx.clone(), platform: globals.platform.clone(), os: globals.os.clone(), + get_ellapsed_millis: globals.get_ellapsed_millis, slot_children_count, node_transform_and_bounds: self.transform_and_bounds.get(), #[cfg(feature = "designtime")] diff --git a/pax-runtime/src/engine/mod.rs b/pax-runtime/src/engine/mod.rs index aec3ec40e..9fd275556 100644 --- a/pax-runtime/src/engine/mod.rs +++ b/pax-runtime/src/engine/mod.rs @@ -14,6 +14,7 @@ use piet::InterpolationMode; use crate::{ComponentInstance, RuntimeContext}; use pax_runtime_api::Platform; +use std::time::Instant; pub mod node_interface; pub mod occlusion; @@ -44,6 +45,7 @@ pub struct Globals { pub os: OS, #[cfg(feature = "designtime")] pub designtime: Rc>, + pub get_ellapsed_millis: Rc u128>, } impl Globals { @@ -257,6 +259,7 @@ impl PaxEngine { viewport_size: (f64, f64), platform: Platform, os: OS, + get_ellapsed_millis: Box u128>, ) -> Self { use crate::api::math::Transform2; use pax_runtime_api::{properties, Functions}; @@ -272,6 +275,7 @@ impl PaxEngine { }), platform, os, + get_ellapsed_millis: Rc::from(get_ellapsed_millis), }; let runtime_context = Rc::new(RuntimeContext::new(globals)); let root_node = @@ -292,6 +296,7 @@ impl PaxEngine { designtime: Rc>, platform: Platform, os: OS, + get_ellapsed_millis: Box u128>, ) -> Self { use pax_runtime_api::{math::Transform2, properties, Functions}; Functions::register_all_functions(); @@ -307,6 +312,7 @@ impl PaxEngine { platform, os, designtime: designtime.clone(), + get_ellapsed_millis: Rc::from(get_ellapsed_millis), }; let mut runtime_context = Rc::new(RuntimeContext::new(