hephae_locale/
lib.rs

1#![allow(internal_features)]
2#![cfg_attr(any(docsrs, docsrs_dep), feature(rustdoc_internals))]
3#![doc = include_str!("../README.md")]
4#![cfg_attr(doc, deny(missing_docs))]
5
6use bevy_ecs::prelude::*;
7
8pub mod arg;
9pub mod cmd;
10pub mod def;
11pub mod loader;
12
13/// Common imports for [`hephae_locale`](crate).
14pub mod prelude {
15    pub use crate::{
16        arg::{LocaleTarget, LocalizeBy},
17        cmd::{LocBundle as _, LocCommandsExt as _, LocEntityExt as _},
18        def::{Locale, LocaleCollection, LocaleKey, LocaleResult},
19    };
20}
21
22/// App plugins for [`hephae_locale`](crate).
23pub mod plugin {
24    use std::{borrow::Cow, marker::PhantomData};
25
26    use bevy_app::{PluginGroupBuilder, prelude::*};
27    use bevy_asset::prelude::*;
28    use bevy_ecs::prelude::*;
29    use hephae_utils::derive::plugin_conf;
30
31    use crate::{
32        HephaeLocaleSystems,
33        arg::{LocaleArg, LocaleTarget, LocalizeBy, localize_target},
34        def::{
35            Locale, LocaleArgs, LocaleChangeEvent, LocaleCollection, LocaleFmt, LocaleKey, LocaleResult, LocaleSrc,
36            update_locale_asset, update_locale_cache, update_locale_result,
37        },
38        loader::{LocaleCollectionLoader, LocaleLoader},
39    };
40
41    plugin_conf! {
42        /// [`LocaleArg`]s you can pass to [`locales`] to conveniently configure them in one go.
43        pub trait ArgConf for LocaleArg, T => locale_arg::<T>()
44    }
45
46    plugin_conf! {
47        /// [`LocaleTarget`]s you can pass to [`locales`] to conveniently configure them in one go.
48        pub trait TargetConf for LocaleTarget, T => locale_target::<T>()
49    }
50
51    /// Entry point for Hephae's localization plugin, configurable with additional localization
52    /// argument types and target localized receivers.
53    #[inline]
54    pub fn locales<C: ArgConf, L: TargetConf>() -> impl PluginGroup {
55        struct LocaleGroup<C: ArgConf, L: TargetConf>(PhantomData<(C, L)>);
56        impl<C: ArgConf, L: TargetConf> PluginGroup for LocaleGroup<C, L> {
57            #[inline]
58            fn build(self) -> PluginGroupBuilder {
59                let mut builder = PluginGroupBuilder::start::<Self>()
60                    .add(|app: &mut App| {
61                        app.register_type::<LocaleFmt>()
62                            .register_type::<LocaleKey>()
63                            .register_type::<LocaleResult>()
64                            .register_type::<LocaleArgs>()
65                            .init_asset::<Locale>()
66                            .register_asset_reflect::<Locale>()
67                            .register_asset_loader(LocaleLoader)
68                            .init_asset::<LocaleCollection>()
69                            .register_asset_reflect::<LocaleCollection>()
70                            .register_asset_loader(LocaleCollectionLoader)
71                            .add_event::<LocaleChangeEvent>()
72                            .register_type::<LocaleChangeEvent>()
73                            .configure_sets(
74                                PostUpdate,
75                                (
76                                    HephaeLocaleSystems::UpdateLocaleAsset,
77                                    HephaeLocaleSystems::UpdateLocaleCache
78                                        .ambiguous_with(HephaeLocaleSystems::UpdateLocaleCache),
79                                    HephaeLocaleSystems::UpdateLocaleResult,
80                                    HephaeLocaleSystems::LocalizeTarget,
81                                )
82                                    .chain(),
83                            )
84                            .add_systems(
85                                PostUpdate,
86                                (
87                                    update_locale_asset.in_set(HephaeLocaleSystems::UpdateLocaleAsset),
88                                    update_locale_result.in_set(HephaeLocaleSystems::UpdateLocaleResult),
89                                ),
90                            );
91                    })
92                    .add(locale_arg::<&'static str>())
93                    .add(locale_arg::<String>())
94                    .add(locale_arg::<Cow<'static, str>>())
95                    .add(locale_arg::<LocalizeBy>())
96                    .add(locale_arg::<u8>())
97                    .add(locale_arg::<u16>())
98                    .add(locale_arg::<u32>())
99                    .add(locale_arg::<u64>())
100                    .add(locale_arg::<u128>())
101                    .add(locale_arg::<i8>())
102                    .add(locale_arg::<i16>())
103                    .add(locale_arg::<i32>())
104                    .add(locale_arg::<i64>())
105                    .add(locale_arg::<i128>())
106                    .add(locale_arg::<f32>())
107                    .add(locale_arg::<f64>());
108
109                builder = C::build(builder);
110                L::build(builder)
111            }
112        }
113
114        LocaleGroup::<C, L>(PhantomData)
115    }
116
117    /// Configures a custom [`LocaleArg`].
118    #[inline]
119    pub fn locale_arg<T: LocaleArg>() -> impl Plugin {
120        |app: &mut App| {
121            app.register_type::<LocaleSrc<T>>().add_systems(
122                PostUpdate,
123                update_locale_cache::<T>.in_set(HephaeLocaleSystems::UpdateLocaleCache),
124            );
125        }
126    }
127
128    /// Configures a custom [`LocaleTarget`].
129    #[inline]
130    pub fn locale_target<T: LocaleTarget>() -> impl Plugin {
131        |app: &mut App| {
132            app.add_systems(PostUpdate, localize_target::<T>.in_set(HephaeLocaleSystems::LocalizeTarget));
133        }
134    }
135}
136
137/// Labels assigned to Hephae systems that are added to [`PostUpdate`](bevy_app::PostUpdate),
138/// responsible over all localizations.
139#[derive(SystemSet, Debug, Copy, Clone, PartialEq, Eq, Hash)]
140pub enum HephaeLocaleSystems {
141    /// Detects locale asset changes (among other things) to notify for cache refreshing.
142    UpdateLocaleAsset,
143    /// Updates each [`LocaleArg`](crate::arg::LocaleArg)s and caches their result.
144    UpdateLocaleCache,
145    /// Combines each [`LocaleArg`](crate::arg::LocaleArg)s into the locale format.
146    UpdateLocaleResult,
147    /// Brings over the results from [`UpdateLocaleResult`](HephaeLocaleSystems::UpdateLocaleResult)
148    /// to the associated [`LocaleTarget`](crate::arg::LocaleTarget) within the [`Entity`].
149    LocalizeTarget,
150}