2025-09-25 02:21:52 +09:00
|
|
|
|
//! State management for FileBox plugin
|
|
|
|
|
|
|
|
|
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
|
|
use std::collections::HashMap;
|
2025-09-25 05:03:59 +09:00
|
|
|
|
use std::fs::File;
|
2025-09-25 02:21:52 +09:00
|
|
|
|
use std::sync::{
|
|
|
|
|
|
atomic::{AtomicU32, Ordering},
|
|
|
|
|
|
Mutex,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ============ FileBox Instance ============
|
|
|
|
|
|
pub struct FileBoxInstance {
|
2025-09-25 05:03:59 +09:00
|
|
|
|
pub file: Option<File>,
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub path: String,
|
|
|
|
|
|
pub buffer: Option<Vec<u8>>, // プラグインが管理するバッファ
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl FileBoxInstance {
|
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
|
Self {
|
|
|
|
|
|
file: None,
|
|
|
|
|
|
path: String::new(),
|
|
|
|
|
|
buffer: None,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-25 06:15:22 +09:00
|
|
|
|
#[allow(dead_code)]
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub fn with_path(path: String) -> Self {
|
|
|
|
|
|
Self {
|
|
|
|
|
|
file: None,
|
|
|
|
|
|
path,
|
|
|
|
|
|
buffer: None,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// グローバルインスタンス管理
|
|
|
|
|
|
pub static INSTANCES: Lazy<Mutex<HashMap<u32, FileBoxInstance>>> =
|
|
|
|
|
|
Lazy::new(|| Mutex::new(HashMap::new()));
|
|
|
|
|
|
|
|
|
|
|
|
// インスタンスIDカウンタ(1開始)
|
|
|
|
|
|
pub static INSTANCE_COUNTER: AtomicU32 = AtomicU32::new(1);
|
|
|
|
|
|
|
|
|
|
|
|
/// Allocate a new instance ID
|
2025-09-25 06:15:22 +09:00
|
|
|
|
#[allow(dead_code)]
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub fn allocate_instance_id() -> u32 {
|
|
|
|
|
|
INSTANCE_COUNTER.fetch_add(1, Ordering::Relaxed)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Store an instance with the given ID
|
2025-09-25 06:15:22 +09:00
|
|
|
|
#[allow(dead_code)]
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub fn store_instance(id: u32, instance: FileBoxInstance) -> Result<(), &'static str> {
|
|
|
|
|
|
match INSTANCES.lock() {
|
|
|
|
|
|
Ok(mut map) => {
|
|
|
|
|
|
map.insert(id, instance);
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
}
|
|
|
|
|
|
Err(_) => Err("Failed to lock instances map"),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove an instance by ID
|
2025-09-25 06:15:22 +09:00
|
|
|
|
#[allow(dead_code)]
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub fn remove_instance(id: u32) -> Option<FileBoxInstance> {
|
|
|
|
|
|
match INSTANCES.lock() {
|
|
|
|
|
|
Ok(mut map) => map.remove(&id),
|
|
|
|
|
|
Err(_) => None,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Get mutable access to an instance
|
2025-09-25 06:15:22 +09:00
|
|
|
|
#[allow(dead_code)]
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub fn with_instance_mut<F, R>(id: u32, f: F) -> Result<R, &'static str>
|
|
|
|
|
|
where
|
|
|
|
|
|
F: FnOnce(&mut FileBoxInstance) -> R,
|
|
|
|
|
|
{
|
|
|
|
|
|
match INSTANCES.lock() {
|
|
|
|
|
|
Ok(mut map) => match map.get_mut(&id) {
|
|
|
|
|
|
Some(instance) => Ok(f(instance)),
|
|
|
|
|
|
None => Err("Instance not found"),
|
|
|
|
|
|
},
|
|
|
|
|
|
Err(_) => Err("Failed to lock instances map"),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Get access to an instance
|
2025-09-25 06:15:22 +09:00
|
|
|
|
#[allow(dead_code)]
|
2025-09-25 02:21:52 +09:00
|
|
|
|
pub fn with_instance<F, R>(id: u32, f: F) -> Result<R, &'static str>
|
|
|
|
|
|
where
|
|
|
|
|
|
F: FnOnce(&FileBoxInstance) -> R,
|
|
|
|
|
|
{
|
|
|
|
|
|
match INSTANCES.lock() {
|
|
|
|
|
|
Ok(map) => match map.get(&id) {
|
|
|
|
|
|
Some(instance) => Ok(f(instance)),
|
|
|
|
|
|
None => Err("Instance not found"),
|
|
|
|
|
|
},
|
|
|
|
|
|
Err(_) => Err("Failed to lock instances map"),
|
|
|
|
|
|
}
|
2025-09-25 05:03:59 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Clear all instances from the registry
|
|
|
|
|
|
pub fn clear_instances() {
|
|
|
|
|
|
if let Ok(mut map) = INSTANCES.lock() {
|
|
|
|
|
|
map.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|