diff --git a/.gitignore b/.gitignore index 0062d901c69f434b6ba9ff948b04d518b8953988..09ad6c6bd43e351302b2b58bc98cd35b8d4fcdb3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ /Cargo.lock .depend /.vscode -copy.bat +copy_debug.bat +copy_release.bat build_no_warning.bat diff --git a/build.bat b/build_debug.bat similarity index 94% rename from build.bat rename to build_debug.bat index f9702559f98255f6022afc811486a6dbae3bd838..a49154ad1699bef00c1b9b82257d2107725eefae 100644 --- a/build.bat +++ b/build_debug.bat @@ -8,4 +8,5 @@ if not defined PI_JS_PROXY_TS_PATH ( cargo clean -p pi_serv cargo b + pause; diff --git a/build_release.bat b/build_release.bat new file mode 100644 index 0000000000000000000000000000000000000000..bf8460bed060e7b670eb731e79fa591f28e73358 --- /dev/null +++ b/build_release.bat @@ -0,0 +1,12 @@ +if not defined PI_JS_PROXY_EXT_CRATES ( + set PI_JS_PROXY_EXT_CRATES=..\pi_core_lib;..\pi_serv_lib +) + +if not defined PI_JS_PROXY_TS_PATH ( + set PI_JS_PROXY_TS_PATH=..\pi_pt +) + +cargo clean -p pi_serv +cargo b --release + +pause; diff --git a/copy1.bat b/copy1.bat deleted file mode 100644 index 42210a37aefdf4dc6b68db0a66f99e8abb8b5fb3..0000000000000000000000000000000000000000 --- a/copy1.bat +++ /dev/null @@ -1,2 +0,0 @@ -copy target\debug\pi_serv.exe E:\work\source\Game\school_1\libs\pi_pt\bin\release -pause; \ No newline at end of file diff --git a/src/hotfix.rs b/src/hotfix.rs index 533d4db8ddc006b11a4df39d62e0a8008ff51bbe..fdb38c9027d90ef2361be875032c8382ba40be8b 100644 --- a/src/hotfix.rs +++ b/src/hotfix.rs @@ -1,11 +1,14 @@ +use std::collections::HashMap; use std::env; use std::ffi::OsString; use std::mem::forget; use std::path::PathBuf; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use dunce::canonicalize; use json::stringify; +use parking_lot::Mutex; use atom::Atom; use file::fs_monitor::{FSChangeEvent, FSListener, FSMonitor, FSMonitorOptions}; @@ -16,6 +19,12 @@ use crate::js_net::HTTP_STATIC_CACHES; use crate::MAIN_ASYNC_RUNTIME; use crate::VID_CONTEXTS; +lazy_static! { + pub static ref HOTFIX_FILES: Arc<Mutex<HashMap<String, usize>>> = + Arc::new(Mutex::new(HashMap::new())); + static ref HOTFIX_VERSION: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0)); +} + const INIT_FILE: &str = "pi_pt/init.js"; fn module_changed(change_path: PathBuf, prefix: PathBuf) { @@ -34,6 +43,11 @@ fn module_changed(change_path: PathBuf, prefix: PathBuf) { break; } + // é€’å¢žç‰ˆæœ¬å· + let ver = HOTFIX_VERSION.fetch_add(1, Ordering::Relaxed); + // 如果是已ç»å˜åœ¨çš„文件,则使用原æ¥çš„版本å·; æ–°æ–‡ä»¶åˆ™ä½¿ç”¨æ–°çš„ç‰ˆæœ¬å· + HOTFIX_FILES.lock().entry(path.clone()).or_insert(ver); + match GRAY_MGR.read().vm_instance(0, vid.clone()) { Some(vm) => { // 虚拟机的æ¯ä¸ªcontexté‡æ–°requireè¯¥æ¨¡å— diff --git a/src/init.rs b/src/init.rs index bd2081ed22022a4654a224d1a065f757d04779a8..547086d734f725534429a06af5352b07b4df6f53 100644 --- a/src/init.rs +++ b/src/init.rs @@ -38,7 +38,12 @@ pub async fn read_init_source(init_exec_path: String) -> String { } } -pub async fn init_js(is_debug_mode: bool, init_vm: vm::Vm, handle: ContextHandle, matches: ArgMatches<'static>) { +pub async fn init_js( + is_debug_mode: bool, + init_vm: vm::Vm, + handle: ContextHandle, + matches: ArgMatches<'static>, +) { let init_exec_path = if is_debug_mode { "../dst_server/pi_pt/debug_init.js".to_string() } else { diff --git a/src/main.rs b/src/main.rs index 9707f3642928d3484ca6c490e861b8b268a3b47c..fda8d13e7ce9e7fddf4f506e1e59b0612eab17cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use std::{env, fs::read_to_string}; use clap::{App, Arg, ArgMatches, SubCommand}; use env_logger; +use json::stringify; use num_cpus::get_physical; use parking_lot::{Condvar, Mutex, RwLock, WaitTimeoutResult}; @@ -57,7 +58,7 @@ use pi_core_builtin::set_external_async_runtime; use pi_core_lib::set_file_async_runtime; use pi_serv_ext::register_ext_functions; use pi_serv_lib::{js_db::global_db_mgr, js_gray::GRAY_MGR}; -use pi_serv_lib::{set_pi_serv_lib_file_runtime, set_pi_serv_lib_main_async_runtime}; +use pi_serv_lib::{set_pi_serv_lib_file_runtime, set_pi_serv_lib_main_async_runtime, set_store_runtime}; #[cfg(feature = "profiling_heap")] use profiling_pi_core::{ console::{set_console_shell_ctrlc_handler, ConsoleShell, ConsoleShellBuilder}, @@ -71,7 +72,7 @@ mod init; mod js_net; use crate::js_net::create_listener_pid; -use hotfix::{hotfix_listen_backend, hotfix_listen_frontend}; +use hotfix::{hotfix_listen_backend, hotfix_listen_frontend, HOTFIX_FILES}; use init::{init_js, read_init_source}; use js_net::{create_http_pid, reg_pi_serv_handle, start_network_services}; @@ -305,6 +306,7 @@ async fn async_main( // åŠ è½½native funtion register_ext_functions(); + set_store_runtime(FILES_ASYNC_RUNTIME.clone()).await; // 注册文件异æ¥è¿è¡Œæ—¶ set_file_async_runtime(FILES_ASYNC_RUNTIME.clone()); set_pi_serv_lib_file_runtime(FILES_ASYNC_RUNTIME.clone()); @@ -425,6 +427,7 @@ fn init_http_listener_pid() { fn reigster_vms_events(workers: &[vm::Vm], is_debug_mode: bool) { // 设置虚拟机的事件回调 for worker in workers { + let vm = worker.clone(); let event_handler = VmEventHandler::new( AsyncRuntime::Local(MAIN_ASYNC_RUNTIME.clone()), move |event, vid| match event { @@ -433,6 +436,55 @@ fn reigster_vms_events(workers: &[vm::Vm], is_debug_mode: bool) { "Vm event handler: VmEventValue::CreatedContext, vid = {:?}, cid = {:?}", vid, context.0 ); + + // éžè°ƒè¯•æ¨¡å¼ä¸‹æ‰éœ€è¦é‡æ–°requireçƒæ›´è¿‡çš„文件 + if !is_debug_mode { + // 获å–å·²ç»çƒæ›´æ–°è¿‡çš„文件 + let mut hotfixed_files = HOTFIX_FILES + .lock() + .iter() + .map(|(key, val)| (key.clone(), val.clone())) + .collect::<Vec<(String, usize)>>(); + // 按版本å·ä»Žå°åˆ°å¤§æŽ’åº + hotfixed_files.sort_by(|a, b| a.1.cmp(&b.1)); + + for (path, _) in hotfixed_files { + let vm = vm.clone(); + let _ = MAIN_ASYNC_RUNTIME.spawn(MAIN_ASYNC_RUNTIME.alloc(), async move { + if let Ok(Some(func)) = vm + .get_property(context.clone(), "self.Module.require") + .await + { + let p = vm + .to_js_value(context.clone(), stringify(path.clone())) + .await + .unwrap() + .unwrap(); + let dir = vm + .to_js_value(context.clone(), stringify("")) + .await + .unwrap() + .unwrap(); + let force = vm + .to_js_value(context.clone(), stringify(true)) + .await + .unwrap() + .unwrap(); + if let Err(_e) = vm + .call(context.clone(), &func, vec![p.clone(), dir, force]) + .await + { + warn!("hotfix call require error"); + } else { + debug!("new context update hotfix file, vid = {:?}, cid = {:?}, path = {:?}", vid, context.0, path); + } + } else { + warn!("get Module.require error"); + } + }); + } + } + VID_CONTEXTS .lock() .entry(vid)