Cache icon results
This commit is contained in:
parent
ae7d3f7123
commit
6fd3b4eba1
25
waycast-core/src/cache/mod.rs
vendored
25
waycast-core/src/cache/mod.rs
vendored
@ -2,11 +2,25 @@ pub mod errors;
|
|||||||
use redb::{Database, ReadableDatabase, ReadableTable, TableDefinition};
|
use redb::{Database, ReadableDatabase, ReadableTable, TableDefinition};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::sync::OnceLock;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use crate::cache::errors::CacheError;
|
use crate::cache::errors::CacheError;
|
||||||
|
|
||||||
const CACHE_TABLE: TableDefinition<&str, &[u8]> = TableDefinition::new("cache");
|
const CACHE_TABLE: TableDefinition<&str, &[u8]> = TableDefinition::new("cache");
|
||||||
|
static CACHE_SINGLETON: OnceLock<Cache> = OnceLock::new();
|
||||||
|
|
||||||
|
pub struct CacheTTL {}
|
||||||
|
|
||||||
|
impl CacheTTL {
|
||||||
|
pub fn hours(hours: u64) -> Option<Duration> {
|
||||||
|
return Some(Duration::from_secs(hours * 60 * 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minutes(minutes: u64) -> Option<Duration> {
|
||||||
|
return Some(Duration::from_secs(minutes * 60));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct CacheEntry<T> {
|
struct CacheEntry<T> {
|
||||||
@ -18,7 +32,13 @@ pub struct Cache {
|
|||||||
db: Database,
|
db: Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<P: AsRef<Path>>(db_path: P) -> Result<Cache, CacheError> {
|
pub fn get() -> &'static Cache {
|
||||||
|
CACHE_SINGLETON.get_or_init(|| new("waycast_cache").expect("Failed to initialize cache :("))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get an existing cache at the given path or
|
||||||
|
// create it if it doesn't exist
|
||||||
|
fn new<P: AsRef<Path>>(db_path: P) -> Result<Cache, CacheError> {
|
||||||
let db = Database::create(db_path)?;
|
let db = Database::create(db_path)?;
|
||||||
|
|
||||||
// Initialize the table if it doesn't exist
|
// Initialize the table if it doesn't exist
|
||||||
@ -47,7 +67,6 @@ impl Cache {
|
|||||||
// Check if entry has expired
|
// Check if entry has expired
|
||||||
if let Some(expires_at) = entry.expires_at {
|
if let Some(expires_at) = entry.expires_at {
|
||||||
if SystemTime::now() < expires_at {
|
if SystemTime::now() < expires_at {
|
||||||
println!("Cache hit");
|
|
||||||
return Ok(entry.data);
|
return Ok(entry.data);
|
||||||
}
|
}
|
||||||
// Entry has expired, continue to recompute
|
// Entry has expired, continue to recompute
|
||||||
@ -57,8 +76,6 @@ impl Cache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Cache miss");
|
|
||||||
|
|
||||||
// Not in cache or expired, compute the value
|
// Not in cache or expired, compute the value
|
||||||
let data = compute();
|
let data = compute();
|
||||||
let expires_at = ttl.map(|duration| SystemTime::now() + duration);
|
let expires_at = ttl.map(|duration| SystemTime::now() + duration);
|
||||||
|
@ -1,70 +1,50 @@
|
|||||||
use std::time::Duration;
|
mod ui;
|
||||||
|
mod util;
|
||||||
|
|
||||||
use waycast_core::cache::Cache;
|
use gtk::prelude::*;
|
||||||
|
use gtk::Application;
|
||||||
|
use ui::gtk::GtkLauncherUI;
|
||||||
|
use waycast_core::WaycastLauncher;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cache: Cache;
|
let app = Application::builder()
|
||||||
if let Ok(db) = waycast_core::cache::new("waycast_cache") {
|
.application_id("dev.thegrind.waycast")
|
||||||
cache = db;
|
.build();
|
||||||
} else {
|
|
||||||
panic!("Failed to open database");
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = cache.remember_with_ttl("test_key", Some(Duration::from_secs(10)), || {
|
app.connect_activate(|app| {
|
||||||
String::from("my cool string value")
|
let mut file_search_plugin = waycast_plugins::file_search::new();
|
||||||
|
|
||||||
|
if let Err(e) = file_search_plugin.add_search_path("/home/javi/working-files/DJ Music/") {
|
||||||
|
eprintln!("{}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut project_plugin = waycast_plugins::projects::new();
|
||||||
|
if let Err(e) = project_plugin.add_search_path("/home/javi/projects") {
|
||||||
|
eprintln!("{}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the core launcher
|
||||||
|
let launcher = WaycastLauncher::new()
|
||||||
|
.add_plugin(Box::new(waycast_plugins::drun::new()))
|
||||||
|
.add_plugin(Box::new(file_search_plugin))
|
||||||
|
.add_plugin(Box::new(project_plugin))
|
||||||
|
.init();
|
||||||
|
|
||||||
|
// Create and show the GTK UI
|
||||||
|
let ui = GtkLauncherUI::new(app, launcher);
|
||||||
|
|
||||||
|
// Apply built-in default styles
|
||||||
|
if let Err(e) = ui.apply_default_css() {
|
||||||
|
eprintln!("Warning: Could not apply default styles: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally apply user CSS overrides
|
||||||
|
// if let Err(_) = ui.apply_css("waycast.css") {
|
||||||
|
// // Silently ignore if user hasn't provided custom CSS
|
||||||
|
// }
|
||||||
|
|
||||||
|
ui.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Ok(val) = result {
|
app.run();
|
||||||
println!("{}", val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// mod ui;
|
|
||||||
// mod util;
|
|
||||||
|
|
||||||
// use gtk::prelude::*;
|
|
||||||
// use gtk::Application;
|
|
||||||
// use ui::gtk::GtkLauncherUI;
|
|
||||||
// use waycast_core::WaycastLauncher;
|
|
||||||
|
|
||||||
// fn main() {
|
|
||||||
// let app = Application::builder()
|
|
||||||
// .application_id("dev.thegrind.waycast")
|
|
||||||
// .build();
|
|
||||||
|
|
||||||
// app.connect_activate(|app| {
|
|
||||||
// let mut file_search_plugin = waycast_plugins::file_search::new();
|
|
||||||
|
|
||||||
// if let Err(e) = file_search_plugin.add_search_path("/home/javi/working-files/DJ Music/") {
|
|
||||||
// eprintln!("{}", e)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut project_plugin = waycast_plugins::projects::new();
|
|
||||||
// if let Err(e) = project_plugin.add_search_path("/home/javi/projects") {
|
|
||||||
// eprintln!("{}", e)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Create the core launcher
|
|
||||||
// let launcher = WaycastLauncher::new()
|
|
||||||
// .add_plugin(Box::new(waycast_plugins::drun::new()))
|
|
||||||
// .add_plugin(Box::new(file_search_plugin))
|
|
||||||
// .add_plugin(Box::new(project_plugin))
|
|
||||||
// .init();
|
|
||||||
|
|
||||||
// // Create and show the GTK UI
|
|
||||||
// let ui = GtkLauncherUI::new(app, launcher);
|
|
||||||
|
|
||||||
// // Apply built-in default styles
|
|
||||||
// if let Err(e) = ui.apply_default_css() {
|
|
||||||
// eprintln!("Warning: Could not apply default styles: {}", e);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Optionally apply user CSS overrides
|
|
||||||
// // if let Err(_) = ui.apply_css("waycast.css") {
|
|
||||||
// // // Silently ignore if user hasn't provided custom CSS
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// ui.show();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// app.run();
|
|
||||||
// }
|
|
||||||
|
@ -13,6 +13,7 @@ use layerShell::LayerShell;
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use waycast_core::cache::CacheTTL;
|
||||||
use waycast_core::WaycastLauncher;
|
use waycast_core::WaycastLauncher;
|
||||||
|
|
||||||
// GObject wrapper to store LauncherListItem in GTK's model system
|
// GObject wrapper to store LauncherListItem in GTK's model system
|
||||||
@ -402,6 +403,25 @@ fn find_icon_file(
|
|||||||
icon_name: &str,
|
icon_name: &str,
|
||||||
size: &str,
|
size: &str,
|
||||||
icon_theme: &IconTheme,
|
icon_theme: &IconTheme,
|
||||||
|
) -> Option<std::path::PathBuf> {
|
||||||
|
let cache_key = format!("icon:{}:{}", icon_name, size);
|
||||||
|
let cache = waycast_core::cache::get();
|
||||||
|
|
||||||
|
let result = cache.remember_with_ttl(&cache_key, CacheTTL::hours(24), || {
|
||||||
|
search_for_icon(icon_name, size, icon_theme)
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Ok(opt_path) = result {
|
||||||
|
return opt_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
search_for_icon(icon_name, size, icon_theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search_for_icon(
|
||||||
|
icon_name: &str,
|
||||||
|
size: &str,
|
||||||
|
icon_theme: &IconTheme,
|
||||||
) -> Option<std::path::PathBuf> {
|
) -> Option<std::path::PathBuf> {
|
||||||
let pixmap_paths: Vec<PathBuf> = icon_theme
|
let pixmap_paths: Vec<PathBuf> = icon_theme
|
||||||
.search_path()
|
.search_path()
|
||||||
@ -439,6 +459,7 @@ fn find_icon_file(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for base in &search_paths {
|
for base in &search_paths {
|
||||||
for size in sizes {
|
for size in sizes {
|
||||||
for cat in &categories {
|
for cat in &categories {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user