use mssf_com::FabricRuntime::{
IFabricConfigurationPackageChangeHandler, IFabricConfigurationPackageChangeHandler_Impl,
};
use crate::runtime::{CodePackageActivationContext, config::ConfigurationPackage};
use super::ConfigurationPackageChangeEvent;
pub trait ConfigurationPackageChangeEventHandler: 'static {
fn on_change(&self, change: &ConfigurationPackageChangeEvent);
}
#[windows_core::implement(IFabricConfigurationPackageChangeHandler)]
#[allow(non_camel_case_types)] pub struct ConfigurationPackageChangeEventHandlerBridge<T>
where
T: ConfigurationPackageChangeEventHandler,
{
inner: T,
}
impl<T> ConfigurationPackageChangeEventHandlerBridge<T>
where
T: ConfigurationPackageChangeEventHandler,
{
pub fn new(inner: T) -> Self {
Self { inner }
}
}
impl<T> IFabricConfigurationPackageChangeHandler_Impl
for ConfigurationPackageChangeEventHandlerBridge_Impl<T>
where
T: ConfigurationPackageChangeEventHandler,
{
fn OnPackageAdded(
&self,
_source: windows_core::Ref<mssf_com::FabricRuntime::IFabricCodePackageActivationContext>,
configpackage: windows_core::Ref<mssf_com::FabricRuntime::IFabricConfigurationPackage>,
) {
let new_package = ConfigurationPackage::from(configpackage.unwrap().clone());
let event = ConfigurationPackageChangeEvent::Addition { new_package };
self.inner.on_change(&event)
}
fn OnPackageRemoved(
&self,
_source: windows_core::Ref<mssf_com::FabricRuntime::IFabricCodePackageActivationContext>,
configpackage: windows_core::Ref<mssf_com::FabricRuntime::IFabricConfigurationPackage>,
) {
let previous_package = ConfigurationPackage::from(configpackage.unwrap().clone());
let event = ConfigurationPackageChangeEvent::Removal { previous_package };
self.inner.on_change(&event)
}
fn OnPackageModified(
&self,
_source: windows_core::Ref<mssf_com::FabricRuntime::IFabricCodePackageActivationContext>,
previousconfigpackage: windows_core::Ref<
mssf_com::FabricRuntime::IFabricConfigurationPackage,
>,
configpackage: windows_core::Ref<mssf_com::FabricRuntime::IFabricConfigurationPackage>,
) {
let new_package = ConfigurationPackage::from(configpackage.unwrap().clone());
let previous_package = ConfigurationPackage::from(previousconfigpackage.unwrap().clone());
let event = ConfigurationPackageChangeEvent::Modification {
previous_package,
new_package,
};
self.inner.on_change(&event)
}
}
pub(crate) struct LambdaConfigurationPackageEventHandler<T>
where
T: Fn(&ConfigurationPackageChangeEvent),
{
f: T,
}
impl<T> LambdaConfigurationPackageEventHandler<T>
where
T: Fn(&ConfigurationPackageChangeEvent) + 'static,
{
pub fn new(f: T) -> Self {
Self { f }
}
}
impl<T> ConfigurationPackageChangeEventHandler for LambdaConfigurationPackageEventHandler<T>
where
T: Fn(&ConfigurationPackageChangeEvent) + 'static,
{
fn on_change(&self, change: &ConfigurationPackageChangeEvent) {
(self.f)(change)
}
}
#[derive(Debug)]
pub struct ConfigurationPackageChangeCallbackHandle(pub(crate) i64);
impl ConfigurationPackageChangeCallbackHandle {
pub const unsafe fn from(com: i64) -> Self {
Self(com)
}
}
#[derive(Debug)]
pub struct AutoConfigurationPackageChangeCallbackHandle {
activation_ctx: CodePackageActivationContext,
handle: Option<ConfigurationPackageChangeCallbackHandle>,
}
impl AutoConfigurationPackageChangeCallbackHandle {
pub fn new<T>(activation_ctx: &CodePackageActivationContext, handler: T) -> crate::Result<Self>
where
T: Fn(&ConfigurationPackageChangeEvent) + 'static,
{
let handle = activation_ctx.register_configuration_package_change_handler(handler)?;
Ok(Self {
activation_ctx: activation_ctx.clone(),
handle: Some(handle),
})
}
}
impl Drop for AutoConfigurationPackageChangeCallbackHandle {
fn drop(&mut self) {
if let Some(my_handle) = self.handle.take() {
self.activation_ctx
.unregister_configuration_package_change_handler(my_handle)
.expect("Unregistering handle should succeed.");
}
}
}