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