Skip to content

Commit 0d267e7

Browse files
committed
Core: Add dedicated BitField template
1 parent 7b9c512 commit 0d267e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+188
-155
lines changed

core/input/input.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Input : public Object {
8585
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
8686

8787
private:
88-
BitField<MouseButtonMask> mouse_button_mask;
88+
BitField<MouseButtonMask> mouse_button_mask = MouseButtonMask::NONE;
8989

9090
RBSet<Key> key_label_pressed;
9191
RBSet<Key> physical_keys_pressed;

core/input/input_enums.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,11 @@ inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
136136

137137
return MouseButtonMask(1 << ((int)button - 1));
138138
}
139+
140+
constexpr MouseButtonMask operator|(MouseButtonMask p_a, MouseButtonMask p_b) {
141+
return static_cast<MouseButtonMask>(static_cast<int>(p_a) | static_cast<int>(p_b));
142+
}
143+
144+
constexpr MouseButtonMask &operator|=(MouseButtonMask &p_a, MouseButtonMask p_b) {
145+
return p_a = p_a | p_b;
146+
}

core/input/input_event.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
230230
}
231231

232232
BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
233-
BitField<KeyModifierMask> mask;
233+
BitField<KeyModifierMask> mask = {};
234234
if (is_ctrl_pressed()) {
235235
mask.set_flag(KeyModifierMask::CTRL);
236236
}
@@ -385,11 +385,11 @@ bool InputEventKey::is_echo() const {
385385
}
386386

387387
Key InputEventKey::get_keycode_with_modifiers() const {
388-
return keycode | (int64_t)get_modifiers_mask();
388+
return keycode | get_modifiers_mask();
389389
}
390390

391391
Key InputEventKey::get_physical_keycode_with_modifiers() const {
392-
return physical_keycode | (int64_t)get_modifiers_mask();
392+
return physical_keycode | get_modifiers_mask();
393393
}
394394

395395
Key InputEventKey::get_key_label_with_modifiers() const {

core/input/input_event.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ class InputEventKey : public InputEventWithModifiers {
208208
class InputEventMouse : public InputEventWithModifiers {
209209
GDCLASS(InputEventMouse, InputEventWithModifiers);
210210

211-
BitField<MouseButtonMask> button_mask;
211+
BitField<MouseButtonMask> button_mask = MouseButtonMask::NONE;
212212

213213
Vector2 pos;
214214
Vector2 global_pos;

core/templates/bit_field.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**************************************************************************/
2+
/* bit_field.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#pragma once
32+
33+
#include "core/typedefs.h"
34+
35+
#include <type_traits>
36+
37+
// TODO: Replace `typename` with enum concept once C++20 concepts/constraints are allowed.
38+
39+
template <typename T>
40+
class BitField {
41+
static_assert(std::is_enum_v<T>);
42+
uint64_t value;
43+
44+
public:
45+
_ALWAYS_INLINE_ constexpr void set_flag(BitField p_flag) { value |= p_flag.value; }
46+
_ALWAYS_INLINE_ constexpr bool has_flag(BitField p_flag) const { return value & p_flag.value; }
47+
_ALWAYS_INLINE_ constexpr bool is_empty() const { return value == 0; }
48+
_ALWAYS_INLINE_ constexpr void clear_flag(BitField p_flag) { value &= ~p_flag.value; }
49+
_ALWAYS_INLINE_ constexpr void clear() { value = 0; }
50+
51+
[[nodiscard]] _ALWAYS_INLINE_ constexpr BitField get_combined(BitField p_other) const { return BitField(value | p_other.value); }
52+
[[nodiscard]] _ALWAYS_INLINE_ constexpr BitField get_shared(BitField p_other) const { return BitField(value & p_other.value); }
53+
[[nodiscard]] _ALWAYS_INLINE_ constexpr BitField get_different(BitField p_other) const { return BitField(value ^ p_other.value); }
54+
55+
_ALWAYS_INLINE_ constexpr BitField() = default;
56+
_ALWAYS_INLINE_ constexpr BitField(T p_value) :
57+
value(static_cast<uint64_t>(p_value)) {}
58+
_ALWAYS_INLINE_ constexpr operator T() const { return static_cast<T>(value); }
59+
60+
// TODO: Unify as single constructor once C++20 `explicit` conditionals are allowed.
61+
62+
template <typename V, std::enable_if_t<std::is_arithmetic_v<V> && std::is_convertible_v<T, int>, int> = 0>
63+
_ALWAYS_INLINE_ constexpr BitField(V p_value) :
64+
value(static_cast<uint64_t>(p_value)) {}
65+
template <typename V, std::enable_if_t<std::is_arithmetic_v<V> && !std::is_convertible_v<T, int>, int> = 0>
66+
_ALWAYS_INLINE_ constexpr explicit BitField(V p_value) :
67+
value(static_cast<uint64_t>(p_value)) {}
68+
template <typename V, std::enable_if_t<std::is_arithmetic_v<V>, int> = 0>
69+
_ALWAYS_INLINE_ constexpr explicit operator V() const { return static_cast<V>(value); }
70+
};
71+
72+
// Implicitly zero-constructible as a trivially-constructible type.
73+
static_assert(is_zero_constructible_v<BitField<Error>>);

core/variant/binder_common.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -123,32 +123,6 @@ VARIANT_ENUM_CAST(Key);
123123
VARIANT_BITFIELD_CAST(KeyModifierMask);
124124
VARIANT_ENUM_CAST(KeyLocation);
125125

126-
static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
127-
a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
128-
return a;
129-
}
130-
131-
static inline Key &operator&=(Key &a, BitField<KeyModifierMask> b) {
132-
a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b.operator int64_t()));
133-
return a;
134-
}
135-
136-
static inline Key operator|(Key a, BitField<KeyModifierMask> b) {
137-
return (Key)((int)a | (int)b.operator int64_t());
138-
}
139-
140-
static inline Key operator&(Key a, BitField<KeyModifierMask> b) {
141-
return (Key)((int)a & (int)b.operator int64_t());
142-
}
143-
144-
static inline Key operator+(BitField<KeyModifierMask> a, Key b) {
145-
return (Key)((int)a.operator int64_t() + (int)b);
146-
}
147-
148-
static inline Key operator|(BitField<KeyModifierMask> a, Key b) {
149-
return (Key)((int)a.operator int64_t() | (int)b);
150-
}
151-
152126
template <>
153127
struct VariantCaster<char32_t> {
154128
static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {

core/variant/type_info.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -209,29 +209,6 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
209209
return GetTypeInfo<T>::get_class_info().class_name;
210210
}
211211

212-
template <typename T>
213-
class BitField {
214-
int64_t value = 0;
215-
216-
public:
217-
_FORCE_INLINE_ BitField<T> &set_flag(T p_flag) {
218-
value |= (int64_t)p_flag;
219-
return *this;
220-
}
221-
_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & (int64_t)p_flag; }
222-
_FORCE_INLINE_ bool is_empty() const { return value == 0; }
223-
_FORCE_INLINE_ void clear_flag(T p_flag) { value &= ~(int64_t)p_flag; }
224-
_FORCE_INLINE_ void clear() { value = 0; }
225-
_FORCE_INLINE_ constexpr BitField() = default;
226-
_FORCE_INLINE_ constexpr BitField(int64_t p_value) { value = p_value; }
227-
_FORCE_INLINE_ constexpr BitField(T p_value) { value = (int64_t)p_value; }
228-
_FORCE_INLINE_ operator int64_t() const { return value; }
229-
_FORCE_INLINE_ BitField<T> operator^(const BitField<T> &p_b) const { return BitField<T>(value ^ p_b.value); }
230-
};
231-
232-
template <typename T>
233-
struct is_zero_constructible<BitField<T>> : std::true_type {};
234-
235212
#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
236213
template <> \
237214
struct GetTypeInfo<m_enum> { \

core/variant/variant.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "core/os/keyboard.h"
5555
#include "core/string/node_path.h"
5656
#include "core/string/ustring.h"
57+
#include "core/templates/bit_field.h"
5758
#include "core/templates/list.h"
5859
#include "core/templates/paged_allocator.h"
5960
#include "core/templates/rid.h"
@@ -485,8 +486,8 @@ class Variant {
485486

486487
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
487488
_FORCE_INLINE_ operator T() const { return static_cast<T>(operator int64_t()); }
488-
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
489-
_FORCE_INLINE_ operator BitField<T>() const { return static_cast<T>(operator int64_t()); }
489+
template <typename T>
490+
_FORCE_INLINE_ operator BitField<T>() const { return static_cast<T>(operator uint64_t()); }
490491

491492
Object *get_validated_object() const;
492493
Object *get_validated_object_with_check(bool &r_previously_freed) const;
@@ -554,9 +555,9 @@ class Variant {
554555
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
555556
_FORCE_INLINE_ Variant(T p_enum) :
556557
Variant(static_cast<int64_t>(p_enum)) {}
557-
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
558+
template <typename T>
558559
_FORCE_INLINE_ Variant(BitField<T> p_bitfield) :
559-
Variant(static_cast<int64_t>(p_bitfield)) {}
560+
Variant(static_cast<uint64_t>(p_bitfield)) {}
560561

561562
// If this changes the table in variant_op must be updated
562563
enum Operator {

drivers/d3d12/rendering_device_driver_d3d12.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3058,7 +3058,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
30583058

30593059
// Translate SPIR-V shaders to DXIL, and collect shader info from the new representation.
30603060
HashMap<ShaderStage, Vector<uint8_t>> dxil_blobs;
3061-
BitField<ShaderStage> stages_processed;
3061+
BitField<ShaderStage> stages_processed = {};
30623062
{
30633063
HashMap<int, nir_shader *> stages_nir_shaders;
30643064

drivers/metal/metal_objects.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@
612612
bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true));
613613
if (shouldClearDepth || shouldClearStencil) {
614614
MDAttachment const &attachment = pass.attachments[ds_index];
615-
BitField<RDD::TextureAspectBits> bits;
615+
BitField<RDD::TextureAspectBits> bits = {};
616616
if (shouldClearDepth && attachment.type & MDAttachmentType::Depth) {
617617
bits.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
618618
}

0 commit comments

Comments
 (0)