diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e3facf4..702c24f 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -28,6 +28,8 @@ tauri-plugin-store = "2.1.0" tauri-plugin-os = "2" # others +log = "0.4.22" +env_logger = "0.11.5" directories = "5.0.1" crabgrab = { git = "https://github.com/qzd1989/CrabGrab.git", features = [ "bitmap", diff --git a/src-tauri/src/common.rs b/src-tauri/src/common.rs index dcc2fdc..bd281f0 100644 --- a/src-tauri/src/common.rs +++ b/src-tauri/src/common.rs @@ -11,8 +11,7 @@ use opencv::prelude::*; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; use std::collections::VecDeque; -use std::path::PathBuf; -use std::sync::{Arc, Mutex}; +use std::sync::Mutex; lazy_static! { pub static ref VERSION: String = String::from("1.0.0"); @@ -28,7 +27,8 @@ lazy_static! { .unwrap() .to_string() }; - pub static ref PROJECT_DIR: Arc>> = Arc::new(Mutex::new(None)); + pub static ref PROJECT_DIR: Mutex> = Mutex::new(None); + pub static ref HAHA: Mutex> = Mutex::new(None); pub static ref PYTHON_EXEC_FILE: String = { #[cfg(target_os = "macos")] { diff --git a/src-tauri/src/frontend_commands/project.rs b/src-tauri/src/frontend_commands/project.rs index 3ccecf3..3e53eb6 100644 --- a/src-tauri/src/frontend_commands/project.rs +++ b/src-tauri/src/frontend_commands/project.rs @@ -1,12 +1,11 @@ use super::AppHandleExt as _; use crate::{ - capture::{listen_primary_display, CAPTURE_SWITCH}, - common::{PROJECT_DIR, PYTHON_EXEC_FILE}, + capture::{listen_primary_display, CAPTURE_SWITCH, FRAME}, + common::{HAHA, PROJECT_DIR, PYTHON_EXEC_FILE}, }; use lazy_static::lazy_static; use std::{ io::{BufRead, BufReader}, - path::PathBuf, process::{Command, Stdio}, sync::{Arc, Mutex}, }; @@ -18,7 +17,6 @@ use install::TESSERACT_DIR; use std::os::windows::process::CommandExt; #[cfg(target_os = "windows")] use windows::Win32::System::Threading::CREATE_NO_WINDOW; -/// project about #[tauri::command] pub fn run(app: AppHandle, file: String) { let app: Arc> = Arc::new(Mutex::new(app)); @@ -35,7 +33,22 @@ pub fn run(app: AppHandle, file: String) { { *CAPTURE_SWITCH.lock().unwrap() = true; listen_primary_display(); + //waiting until the frame is not empty + loop { + if FRAME.lock().unwrap().is_some() { + break; + } + } } + println!("set haha"); + *HAHA.lock().unwrap() = Some("huhu".to_string()); + println!( + "haha: {:?}", + HAHA.lock() + .unwrap() + .clone() + .unwrap_or("none from run".to_string()) + ); std::thread::spawn(move || { let handle = Command::new(PYTHON_EXEC_FILE.to_string()) .arg(file) @@ -140,16 +153,15 @@ pub fn stop(app: AppHandle) { #[tauri::command] pub fn set_project(path: String) { - let path_buff = PathBuf::from(path); - *PROJECT_DIR.lock().unwrap() = Some(path_buff); + *PROJECT_DIR.lock().unwrap() = Some(path); } #[tauri::command] pub fn get_project_dir() -> Result { - let project_path = PROJECT_DIR.lock().unwrap(); - match project_path.as_ref() { - Some(path_buff) => Ok(path_buff.to_str().unwrap().to_string()), - None => Ok("".to_string()), + let project_path = PROJECT_DIR.lock().unwrap().clone(); + match project_path { + Some(path) => Ok(path), + None => Err("project dir is not set".to_string()), } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 3c8909a..914ab09 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -12,6 +12,7 @@ use pyo3::prelude::*; //for frontend #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { + env_logger::init(); let frontend = tauri::Builder::default() .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_global_shortcut::Builder::new().build()) diff --git a/src-tauri/src/python_commands/find.rs b/src-tauri/src/python_commands/find.rs index c20e663..577aa87 100644 --- a/src-tauri/src/python_commands/find.rs +++ b/src-tauri/src/python_commands/find.rs @@ -1,67 +1,275 @@ -use crate::common::{HexColor, LocatingColor}; +use crate::common::HAHA; +use crate::find; +use crate::{ + capture::FRAME, + common::{HexColor, LocatingColor, PROJECT_DIR}, + utils::fs::exists, +}; use pyo3::prelude::*; +use std::path::PathBuf; + +fn project_check() -> bool { + let project_dir = PROJECT_DIR.lock().unwrap().clone(); + match project_dir { + Some(_) => true, + None => false, + } +} + +fn frame_check() -> bool { + if FRAME.lock().unwrap().is_none() { + return false; + } + true +} + +const EMPTY_WEIGHT_POINT: (i32, i32, f64) = (-1, -1, 0.0); +const EMPTY_WEIGHT_POINTS: Vec<(i32, i32, f64)> = Vec::new(); +const EMPTY_POINT: (i32, i32) = (-1, -1); +const EMPTY_LOCATING_COLORS: Vec<(i32, i32, HexColor)> = Vec::new(); +const EMPTY_TEXT: &str = ""; #[pyfunction] -pub fn find_image(path: String, start: (i32, i32), end: (i32, i32), threshold: f64) -> (f64, f64) { - (-1.0, -1.0) +pub fn find_haha(py: Python) { + println!("find_haha"); + let haha = py.allow_threads(|| { + HAHA.lock() + .unwrap() + .clone() + .unwrap_or("none from find_haha".to_string()) + }); + println!("find_haha: {}", haha); +} + +#[pyfunction] +pub fn find_image( + path: String, //such as "subfolder/imageFileName" + start: (u32, u32), + end: (u32, u32), + threshold: f64, +) -> (i32, i32, f64) { + if !project_check() { + println!("project_check error"); + return EMPTY_WEIGHT_POINT; + } + if !frame_check() { + println!("frame_check error"); + return EMPTY_WEIGHT_POINT; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let project_path = PROJECT_DIR.lock().unwrap().clone().unwrap(); + let project_pathbuf = PathBuf::from(project_path); + let full_path = format!( + "{}{}", + project_pathbuf + .join("resources") + .join(path) + .to_str() + .unwrap() + .to_string(), + ".png" + ); + println!("full path is {:?}", full_path.clone()); + if let Err(error) = exists(full_path.clone()) { + println!("exists caused error: {}", error.to_string()); + return EMPTY_WEIGHT_POINT; + } + if !exists(full_path.clone()).unwrap() { + println!("file not exist"); + return EMPTY_WEIGHT_POINT; + } + let (width, height) = (end.0 - start.0, end.1 - start.1); + if width <= 0 || height <= 0 { + println!("width ({}) or height ({}) is zero", width, height); + return EMPTY_WEIGHT_POINT; + } + let template = image::open(full_path.clone()).unwrap().to_rgba8(); + match find::image::find_one(frame, template, start.0, start.1, width, height, threshold) { + Ok(weight_point) => ( + weight_point.point.x as i32, + weight_point.point.y as i32, + weight_point.weight, + ), + Err(error) => { + println!("find_one caused error: {}", error.to_string()); + EMPTY_WEIGHT_POINT + } + } } #[pyfunction] pub fn find_images( path: String, - start: (i32, i32), - end: (i32, i32), + start: (u32, u32), + end: (u32, u32), threshold: f64, -) -> Vec<(f64, f64)> { - let vec = Vec::new(); - vec +) -> Vec<(i32, i32, f64)> { + let mut vecs = Vec::new(); + if !project_check() { + return EMPTY_WEIGHT_POINTS; + } + if !frame_check() { + return EMPTY_WEIGHT_POINTS; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let project_path = PROJECT_DIR.lock().unwrap().clone().unwrap(); + let project_pathbuf = PathBuf::from(project_path); + let full_path = format!( + "{}{}", + project_pathbuf + .join("resources") + .join(path) + .to_str() + .unwrap() + .to_string(), + ".png" + ); + println!("full_path: {}", full_path.clone()); + if let Err(_) = exists(full_path.clone()) { + return EMPTY_WEIGHT_POINTS; + } + if !exists(full_path.clone()).unwrap() { + return EMPTY_WEIGHT_POINTS; + } + let (width, height) = (end.0 - start.0, end.1 - start.1); + if width <= 0 || height <= 0 { + return EMPTY_WEIGHT_POINTS; + } + let template = image::open(full_path.clone()).unwrap().to_rgba8(); + match find::image::find_multiple(frame, template, start.0, start.1, width, height, threshold) { + Ok(weight_points) => { + for weight_point in weight_points { + vecs.push(( + weight_point.point.x as i32, + weight_point.point.y as i32, + weight_point.weight, + )) + } + vecs + } + Err(_) => EMPTY_WEIGHT_POINTS, + } } #[pyfunction] -pub fn global_find_image(path: String, threshold: f64) -> (f64, f64) { - (-1.0, -1.0) +pub fn global_find_image(path: String, threshold: f64) -> (i32, i32, f64) { + if !project_check() { + return EMPTY_WEIGHT_POINT; + } + if !frame_check() { + return EMPTY_WEIGHT_POINT; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (frame.width, frame.height); + find_image(path, (0, 0), (width, height), threshold) } #[pyfunction] -pub fn global_find_images(path: String, threshold: f64) -> Vec<(f64, f64)> { - let vec = Vec::new(); - vec +pub fn global_find_images(path: String, threshold: f64) -> Vec<(i32, i32, f64)> { + if !project_check() { + return EMPTY_WEIGHT_POINTS; + } + if !frame_check() { + return EMPTY_WEIGHT_POINTS; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (frame.width, frame.height); + find_images(path, (0, 0), (width, height), threshold) } #[pyfunction] pub fn find_locating_color( locating_colors: Vec, - start: (i32, i32), - end: (i32, i32), + start: (u32, u32), + end: (u32, u32), offsets: (u8, u8, u8), -) -> (f64, f64) { - (-1.0, -1.0) +) -> (i32, i32) { + if !frame_check() { + return EMPTY_POINT; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (end.0 - start.0, end.1 - start.1); + match find::locating_color::find( + frame, + locating_colors, + start.0, + start.1, + width, + height, + offsets.0, + offsets.1, + offsets.2, + ) { + Some(point) => (point.x as i32, point.y as i32), + None => EMPTY_POINT, + } } #[pyfunction] pub fn global_find_locating_color( locating_colors: Vec, offsets: (u8, u8, u8), -) -> (f64, f64) { - (-1.0, -1.0) +) -> (i32, i32) { + if !frame_check() { + return EMPTY_POINT; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (frame.width, frame.height); + find_locating_color(locating_colors, (0, 0), (width, height), offsets) } #[pyfunction] pub fn find_color( hex_colors: Vec, - start: (i32, i32), - end: (i32, i32), + start: (u32, u32), + end: (u32, u32), offsets: (u8, u8, u8), -) -> (f64, f64) { - (-1.0, -1.0) +) -> Vec<(i32, i32, HexColor)> { + if !frame_check() { + return EMPTY_LOCATING_COLORS; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (end.0 - start.0, end.1 - start.1); + let mut vecs = Vec::new(); + match find::color::find( + frame, hex_colors, start.0, start.1, width, height, offsets.0, offsets.1, offsets.2, + ) { + Ok(locating_colors) => { + for locating_color in locating_colors { + vecs.push(( + locating_color.point.x as i32, + locating_color.point.y as i32, + locating_color.hex.clone(), + )) + } + vecs + } + Err(_) => EMPTY_LOCATING_COLORS, + } } #[pyfunction] -pub fn global_find_color(hex_colors: Vec, offsets: (u8, u8, u8)) -> (f64, f64) { - (-1.0, -1.0) +pub fn global_find_color( + hex_colors: Vec, + offsets: (u8, u8, u8), +) -> Vec<(i32, i32, HexColor)> { + if !frame_check() { + return EMPTY_LOCATING_COLORS; + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (frame.width, frame.height); + find_color(hex_colors, (0, 0), (width, height), offsets) } #[pyfunction] -pub fn recognize_text(start: (i32, i32), end: (i32, i32), languages: Vec) -> String { - "".to_string() +pub fn find_text(start: (u32, u32), end: (u32, u32), langs: Vec) -> String { + if !frame_check() { + return EMPTY_TEXT.to_string(); + } + let frame = FRAME.lock().unwrap().clone().unwrap(); + let (width, height) = (end.0 - start.0, end.1 - start.1); + match find::text::recognize(frame, langs, start.0, start.1, width, height) { + Ok(text) => text, + Err(_) => EMPTY_TEXT.to_string(), + } } diff --git a/src-tauri/src/python_commands/mod.rs b/src-tauri/src/python_commands/mod.rs index f124ec7..91f068f 100644 --- a/src-tauri/src/python_commands/mod.rs +++ b/src-tauri/src/python_commands/mod.rs @@ -27,10 +27,11 @@ pub fn find_moudle(parent: &Bound<'_, PyModule>) -> PyResult<()> { find.add_function(wrap_pyfunction!(find::find_images, &find)?)?; find.add_function(wrap_pyfunction!(find::find_locating_color, &find)?)?; find.add_function(wrap_pyfunction!(find::find_color, &find)?)?; - find.add_function(wrap_pyfunction!(find::recognize_text, &find)?)?; + find.add_function(wrap_pyfunction!(find::find_text, &find)?)?; find.add_function(wrap_pyfunction!(find::global_find_image, &find)?)?; find.add_function(wrap_pyfunction!(find::global_find_images, &find)?)?; find.add_function(wrap_pyfunction!(find::global_find_locating_color, &find)?)?; find.add_function(wrap_pyfunction!(find::global_find_color, &find)?)?; + find.add_function(wrap_pyfunction!(find::find_haha, &find)?)?; parent.add_submodule(&find) } diff --git a/src/views/Tree.vue b/src/views/Tree.vue index 13cfa3a..b73b6fb 100644 --- a/src/views/Tree.vue +++ b/src/views/Tree.vue @@ -14,6 +14,7 @@ import { ElMessageBox } from "element-plus"; import { msgError, msgSuccess, msgInfo } from "./../utils/msg"; import { join, basename, extname, sep } from "@tauri-apps/api/path"; import { useElementSize } from "@vueuse/core"; +import { invoke } from "@tauri-apps/api/core"; import { open as openDialog } from "@tauri-apps/plugin-dialog"; import { LocalStore } from "../stores/local"; import { emitTo } from "@tauri-apps/api/event"; @@ -356,11 +357,12 @@ async function newProject() { newProjectVisible.value = true; } async function openProject(result) { - const storeCommit = async (projectPath) => { - store.commit("currentProjectPath", projectPath); - store.commit("currentProjectName", await basename(projectPath)); + const storeCommit = async (path) => { + store.commit("currentProjectPath", path); + store.commit("currentProjectName", await basename(path)); //active send project path to monitor - await emitTo("monitor", "update:project-path", { path: projectPath }); + await emitTo("monitor", "update:project-path", { path }); + await invoke("set_project", { path }); }; //come from newProject if (result.project != undefined) {