godot_core/registry/
constant.rs

1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8use godot_ffi as sys;
9use sys::interface_fn;
10
11use crate::builtin::StringName;
12use crate::meta::ClassId;
13
14/// A constant named `name` with the value `value`.
15pub struct IntegerConstant {
16    name: StringName,
17    value: i64,
18}
19
20impl IntegerConstant {
21    pub fn new<T>(name: &str, value: T) -> Self
22    where
23        T: TryInto<i64> + Copy + std::fmt::Debug,
24    {
25        Self {
26            name: StringName::from(name),
27            value: value.try_into().ok().unwrap_or_else(|| {
28                panic!("exported constant `{value:?}` must be representable as `i64`")
29            }),
30        }
31    }
32
33    fn register(&self, class_name: ClassId, enum_name: &StringName, is_bitfield: bool) {
34        unsafe {
35            interface_fn!(classdb_register_extension_class_integer_constant)(
36                sys::get_library(),
37                class_name.string_sys(),
38                enum_name.string_sys(),
39                self.name.string_sys(),
40                self.value,
41                sys::conv::bool_to_sys(is_bitfield),
42            );
43        }
44    }
45}
46
47/// Whether the constant should be interpreted as a single integer, an enum with several variants, or a
48/// bitfield with several flags.
49pub enum ConstantKind {
50    Integer(IntegerConstant),
51    Enum {
52        name: StringName,
53        enumerators: Vec<IntegerConstant>,
54    },
55    Bitfield {
56        name: StringName,
57        flags: Vec<IntegerConstant>,
58    },
59}
60
61impl ConstantKind {
62    fn register(&self, class_name: ClassId) {
63        match self {
64            ConstantKind::Integer(integer) => {
65                integer.register(class_name, &StringName::default(), false)
66            }
67            ConstantKind::Enum { name, enumerators } => {
68                for enumerator in enumerators.iter() {
69                    enumerator.register(class_name, name, false)
70                }
71            }
72            ConstantKind::Bitfield { name, flags } => {
73                for flag in flags.iter() {
74                    flag.register(class_name, name, true)
75                }
76            }
77        }
78    }
79}
80
81/// All the info needed to export a constant to Godot.
82pub struct ExportConstant {
83    class_name: ClassId,
84    kind: ConstantKind,
85}
86
87impl ExportConstant {
88    pub fn new(class_name: ClassId, kind: ConstantKind) -> Self {
89        Self { class_name, kind }
90    }
91
92    pub fn register(&self) {
93        self.kind.register(self.class_name)
94    }
95}