ixa/macros/
define_data_plugin.rs

1/// Helper for `define_data_plugin`
2#[macro_export]
3macro_rules! __define_data_plugin {
4    ($data_plugin:ident, $data_container:ty, |$ctx:ident| $body:expr) => {
5        struct $data_plugin;
6
7        impl $crate::DataPlugin for $data_plugin {
8            type DataContainer = $data_container;
9
10            fn init<C: $crate::PluginContext>($ctx: &C) -> Self::DataContainer {
11                $body
12            }
13
14            fn index_within_context() -> usize {
15                // This static must be initialized with a compile-time constant expression.
16                // We use `usize::MAX` as a sentinel to mean "uninitialized". This
17                // static variable is shared among all instances of this data plugin type.
18                static INDEX: std::sync::atomic::AtomicUsize =
19                    std::sync::atomic::AtomicUsize::new(usize::MAX);
20
21                // Fast path: already initialized.
22                let index = INDEX.load(std::sync::atomic::Ordering::Relaxed);
23                if index != usize::MAX {
24                    return index;
25                }
26
27                // Slow path: initialize it.
28                $crate::initialize_data_plugin_index(&INDEX)
29            }
30        }
31
32        $crate::paste::paste! {
33            $crate::ctor::declarative::ctor!{
34                #[ctor]
35                fn [<_register_plugin_$data_plugin:snake>]() {
36                    $crate::add_data_plugin_to_registry::<$data_plugin>()
37                }
38            }
39        }
40    };
41}
42
43/// Defines a new type for storing data in Context.
44#[macro_export]
45macro_rules! define_data_plugin {
46    ($data_plugin:ident, $data_container:ty, |$ctx:ident| $body:expr) => {
47        $crate::__define_data_plugin!($data_plugin, $data_container, |$ctx| $body);
48    };
49
50    ($data_plugin:ident, $data_container:ty, $default: expr) => {
51        $crate::__define_data_plugin!($data_plugin, $data_container, |_context| $default);
52    };
53}