use std::sync::Arc; use std::collections::HashMap; use parking_lot::RwLock; use elements::Module; use interpreter::Error; use interpreter::env::env_module; use interpreter::module::{ModuleInstance, ModuleInstanceInterface}; /// Program instance. Program is a set of instantiated modules. pub struct ProgramInstance { /// Shared data reference. essence: Arc, } /// Program instance essence. pub struct ProgramInstanceEssence { /// Loaded modules. modules: RwLock>>, } impl ProgramInstance { /// Create new program instance. pub fn new() -> Result { Ok(ProgramInstance { essence: Arc::new(ProgramInstanceEssence::new()?), }) } /// Instantiate module. pub fn add_module(&self, name: &str, module: Module) -> Result, Error> { let module_instance = Arc::new(ModuleInstance::new(Arc::downgrade(&self.essence), module)?); // replace existing module with the same name with new one self.essence.modules.write().insert(name.into(), module_instance.clone()); Ok(module_instance) } /// Get one of the modules by name pub fn module(&self, name: &str) -> Option> { self.essence.module(name) } } impl ProgramInstanceEssence { /// Create new program essence. pub fn new() -> Result { let mut modules = HashMap::new(); let env_module: Arc = Arc::new(env_module()?); modules.insert("env".into(), env_module); Ok(ProgramInstanceEssence { modules: RwLock::new(modules), }) } /// Get module reference. pub fn module(&self, name: &str) -> Option> { self.modules.read().get(name).cloned() } }