mirror of
https://github.com/godotengine/godot.git
synced 2026-01-06 10:11:57 +03:00
Use BitField<> in core type masks
* All core types masks are now correctly marked as bitfields. * The enum hacks in MouseButtonMask and many other types are gone. This ensures that binders to other languages non C++ can actually implement type safe bitmasks. * Most bitmask operations replaced by functions in BitField<> * Key is still a problem because its enum and mask at the same time. While it kind of works in C++, this most likely can't be implemented safely in other languages and will have to be changed at some point. Mostly left as-is. * Documentation and API dump updated to reflect bitfields in core types.
This commit is contained in:
@@ -237,7 +237,7 @@ bool Input::is_anything_pressed() const {
|
||||
}
|
||||
return !keys_pressed.is_empty() ||
|
||||
!joy_buttons_pressed.is_empty() ||
|
||||
mouse_button_mask > MouseButton::NONE;
|
||||
!mouse_button_mask.is_empty();
|
||||
}
|
||||
|
||||
bool Input::is_key_pressed(Key p_keycode) const {
|
||||
@@ -252,7 +252,7 @@ bool Input::is_physical_key_pressed(Key p_keycode) const {
|
||||
|
||||
bool Input::is_mouse_button_pressed(MouseButton p_button) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
return (mouse_button_mask & mouse_button_to_mask(p_button)) != MouseButton::NONE;
|
||||
return mouse_button_mask.has_flag(mouse_button_to_mask(p_button));
|
||||
}
|
||||
|
||||
static JoyAxis _combine_device(JoyAxis p_value, int p_device) {
|
||||
@@ -504,9 +504,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
|
||||
if (mb.is_valid()) {
|
||||
if (mb->is_pressed()) {
|
||||
mouse_button_mask |= mouse_button_to_mask(mb->get_button_index());
|
||||
mouse_button_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
|
||||
} else {
|
||||
mouse_button_mask &= ~mouse_button_to_mask(mb->get_button_index());
|
||||
mouse_button_mask.clear_flag(mouse_button_to_mask(mb->get_button_index()));
|
||||
}
|
||||
|
||||
Point2 pos = mb->get_global_position();
|
||||
@@ -534,7 +534,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
Vector2 relative = mm->get_relative();
|
||||
mouse_velocity_track.update(relative);
|
||||
|
||||
if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && (mm->get_button_mask() & MouseButton::LEFT) != MouseButton::NONE) {
|
||||
if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
|
||||
Ref<InputEventScreenDrag> drag_event;
|
||||
drag_event.instantiate();
|
||||
|
||||
@@ -585,11 +585,14 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
button_event->set_pressed(st->is_pressed());
|
||||
button_event->set_button_index(MouseButton::LEFT);
|
||||
button_event->set_double_click(st->is_double_tap());
|
||||
|
||||
BitField<MouseButtonMask> ev_bm = mouse_button_mask;
|
||||
if (st->is_pressed()) {
|
||||
button_event->set_button_mask(MouseButton(mouse_button_mask | MouseButton::MASK_LEFT));
|
||||
ev_bm.set_flag(MouseButtonMask::LEFT);
|
||||
} else {
|
||||
button_event->set_button_mask(MouseButton(mouse_button_mask & ~MouseButton::MASK_LEFT));
|
||||
ev_bm.clear_flag(MouseButtonMask::LEFT);
|
||||
}
|
||||
button_event->set_button_mask(ev_bm);
|
||||
|
||||
_parse_input_event_impl(button_event, true);
|
||||
}
|
||||
@@ -740,7 +743,7 @@ Point2 Input::get_last_mouse_velocity() {
|
||||
return mouse_velocity_track.velocity;
|
||||
}
|
||||
|
||||
MouseButton Input::get_mouse_button_mask() const {
|
||||
BitField<MouseButtonMask> Input::get_mouse_button_mask() const {
|
||||
return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
|
||||
}
|
||||
|
||||
@@ -821,7 +824,9 @@ void Input::ensure_touch_mouse_raised() {
|
||||
button_event->set_global_position(mouse_pos);
|
||||
button_event->set_pressed(false);
|
||||
button_event->set_button_index(MouseButton::LEFT);
|
||||
button_event->set_button_mask(MouseButton(mouse_button_mask & ~MouseButton::MASK_LEFT));
|
||||
BitField<MouseButtonMask> ev_bm = mouse_button_mask;
|
||||
ev_bm.clear_flag(MouseButtonMask::LEFT);
|
||||
button_event->set_button_mask(ev_bm);
|
||||
|
||||
_parse_input_event_impl(button_event, true);
|
||||
}
|
||||
@@ -1022,7 +1027,7 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) {
|
||||
}
|
||||
}
|
||||
|
||||
void Input::joy_hat(int p_device, HatMask p_val) {
|
||||
void Input::joy_hat(int p_device, BitField<HatMask> p_val) {
|
||||
_THREAD_SAFE_METHOD_;
|
||||
const Joypad &joy = joy_names[p_device];
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
|
||||
|
||||
private:
|
||||
MouseButton mouse_button_mask = MouseButton::NONE;
|
||||
BitField<MouseButtonMask> mouse_button_mask;
|
||||
|
||||
RBSet<Key> physical_keys_pressed;
|
||||
RBSet<Key> keys_pressed;
|
||||
@@ -273,7 +273,7 @@ public:
|
||||
|
||||
Point2 get_mouse_position() const;
|
||||
Vector2 get_last_mouse_velocity();
|
||||
MouseButton get_mouse_button_mask() const;
|
||||
BitField<MouseButtonMask> get_mouse_button_mask() const;
|
||||
|
||||
void warp_mouse(const Vector2 &p_position);
|
||||
Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
|
||||
@@ -310,7 +310,7 @@ public:
|
||||
void parse_mapping(String p_mapping);
|
||||
void joy_button(int p_device, JoyButton p_button, bool p_pressed);
|
||||
void joy_axis(int p_device, JoyAxis p_axis, float p_value);
|
||||
void joy_hat(int p_device, HatMask p_val);
|
||||
void joy_hat(int p_device, BitField<HatMask> p_val);
|
||||
|
||||
void add_joy_mapping(String p_mapping, bool p_update_existing = false);
|
||||
void remove_joy_mapping(String p_guid);
|
||||
|
||||
@@ -119,59 +119,18 @@ enum class MouseButton {
|
||||
WHEEL_RIGHT = 7,
|
||||
MB_XBUTTON1 = 8, // "XBUTTON1" is a reserved word on Windows.
|
||||
MB_XBUTTON2 = 9, // "XBUTTON2" is a reserved word on Windows.
|
||||
MASK_LEFT = (1 << (LEFT - 1)),
|
||||
MASK_RIGHT = (1 << (RIGHT - 1)),
|
||||
MASK_MIDDLE = (1 << (MIDDLE - 1)),
|
||||
MASK_XBUTTON1 = (1 << (MB_XBUTTON1 - 1)),
|
||||
MASK_XBUTTON2 = (1 << (MB_XBUTTON2 - 1)),
|
||||
};
|
||||
|
||||
inline MouseButton mouse_button_to_mask(MouseButton button) {
|
||||
return MouseButton(1 << ((int)button - 1));
|
||||
}
|
||||
enum class MouseButtonMask {
|
||||
LEFT = (1 << (int(MouseButton::LEFT) - 1)),
|
||||
RIGHT = (1 << (int(MouseButton::RIGHT) - 1)),
|
||||
MIDDLE = (1 << (int(MouseButton::MIDDLE) - 1)),
|
||||
MB_XBUTTON1 = (1 << (int(MouseButton::MB_XBUTTON1) - 1)),
|
||||
MB_XBUTTON2 = (1 << (int(MouseButton::MB_XBUTTON2) - 1)),
|
||||
};
|
||||
|
||||
inline MouseButton operator&(MouseButton a, MouseButton b) {
|
||||
return (MouseButton)((int)a & (int)b);
|
||||
}
|
||||
|
||||
inline MouseButton operator|(MouseButton a, MouseButton b) {
|
||||
return (MouseButton)((int)a | (int)b);
|
||||
}
|
||||
|
||||
inline MouseButton operator^(MouseButton a, MouseButton b) {
|
||||
return (MouseButton)((int)a ^ (int)b);
|
||||
}
|
||||
|
||||
inline MouseButton &operator|=(MouseButton &a, MouseButton b) {
|
||||
return (MouseButton &)((int &)a |= (int)b);
|
||||
}
|
||||
|
||||
inline MouseButton &operator&=(MouseButton &a, MouseButton b) {
|
||||
return (MouseButton &)((int &)a &= (int)b);
|
||||
}
|
||||
|
||||
inline MouseButton operator~(MouseButton a) {
|
||||
return (MouseButton)(~(int)a);
|
||||
}
|
||||
|
||||
inline HatMask operator|(HatMask a, HatMask b) {
|
||||
return (HatMask)((int)a | (int)b);
|
||||
}
|
||||
|
||||
inline HatMask operator&(HatMask a, HatMask b) {
|
||||
return (HatMask)((int)a & (int)b);
|
||||
}
|
||||
|
||||
inline HatMask &operator&=(HatMask &a, HatMask b) {
|
||||
return (HatMask &)((int &)a &= (int)b);
|
||||
}
|
||||
|
||||
inline HatMask &operator|=(HatMask &a, HatMask b) {
|
||||
return (HatMask &)((int &)a |= (int)b);
|
||||
}
|
||||
|
||||
inline HatMask operator~(HatMask a) {
|
||||
return (HatMask)(~(int)a);
|
||||
inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
|
||||
return MouseButtonMask(1 << ((int)button - 1));
|
||||
}
|
||||
|
||||
#endif // INPUT_ENUMS_H
|
||||
|
||||
@@ -216,25 +216,25 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
|
||||
set_meta_pressed(event->is_meta_pressed());
|
||||
}
|
||||
|
||||
Key InputEventWithModifiers::get_modifiers_mask() const {
|
||||
Key mask = Key::NONE;
|
||||
BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
|
||||
BitField<KeyModifierMask> mask;
|
||||
if (is_ctrl_pressed()) {
|
||||
mask |= KeyModifierMask::CTRL;
|
||||
mask.set_flag(KeyModifierMask::CTRL);
|
||||
}
|
||||
if (is_shift_pressed()) {
|
||||
mask |= KeyModifierMask::SHIFT;
|
||||
mask.set_flag(KeyModifierMask::SHIFT);
|
||||
}
|
||||
if (is_alt_pressed()) {
|
||||
mask |= KeyModifierMask::ALT;
|
||||
mask.set_flag(KeyModifierMask::ALT);
|
||||
}
|
||||
if (is_meta_pressed()) {
|
||||
mask |= KeyModifierMask::META;
|
||||
mask.set_flag(KeyModifierMask::META);
|
||||
}
|
||||
if (is_command_or_control_autoremap()) {
|
||||
#ifdef MACOS_ENABLED
|
||||
mask |= KeyModifierMask::META;
|
||||
mask.set_flag(KeyModifierMask::META);
|
||||
#else
|
||||
mask |= KeyModifierMask::CTRL;
|
||||
mask.set_flag(KeyModifierMask::CTRL);
|
||||
#endif
|
||||
}
|
||||
return mask;
|
||||
@@ -356,11 +356,11 @@ bool InputEventKey::is_echo() const {
|
||||
}
|
||||
|
||||
Key InputEventKey::get_keycode_with_modifiers() const {
|
||||
return keycode | get_modifiers_mask();
|
||||
return keycode | (int64_t)get_modifiers_mask();
|
||||
}
|
||||
|
||||
Key InputEventKey::get_physical_keycode_with_modifiers() const {
|
||||
return physical_keycode | get_modifiers_mask();
|
||||
return physical_keycode | (int64_t)get_modifiers_mask();
|
||||
}
|
||||
|
||||
String InputEventKey::as_text() const {
|
||||
@@ -440,8 +440,8 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool p_exact_ma
|
||||
} else {
|
||||
match = get_physical_keycode() == key->get_physical_keycode();
|
||||
}
|
||||
Key action_mask = get_modifiers_mask();
|
||||
Key key_mask = key->get_modifiers_mask();
|
||||
Key action_mask = (Key)(int64_t)get_modifiers_mask();
|
||||
Key key_mask = (Key)(int64_t)key->get_modifiers_mask();
|
||||
if (key->is_pressed()) {
|
||||
match &= (action_mask & key_mask) == action_mask;
|
||||
}
|
||||
@@ -505,12 +505,12 @@ void InputEventKey::_bind_methods() {
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventMouse::set_button_mask(MouseButton p_mask) {
|
||||
void InputEventMouse::set_button_mask(BitField<MouseButtonMask> p_mask) {
|
||||
button_mask = p_mask;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
MouseButton InputEventMouse::get_button_mask() const {
|
||||
BitField<MouseButtonMask> InputEventMouse::get_button_mask() const {
|
||||
return button_mask;
|
||||
}
|
||||
|
||||
@@ -610,8 +610,8 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool p_
|
||||
}
|
||||
|
||||
bool match = button_index == mb->button_index;
|
||||
Key action_modifiers_mask = get_modifiers_mask();
|
||||
Key button_modifiers_mask = mb->get_modifiers_mask();
|
||||
Key action_modifiers_mask = (Key)(int64_t)get_modifiers_mask();
|
||||
Key button_modifiers_mask = (Key)(int64_t)mb->get_modifiers_mask();
|
||||
if (mb->is_pressed()) {
|
||||
match &= (action_modifiers_mask & button_modifiers_mask) == action_modifiers_mask;
|
||||
}
|
||||
@@ -808,26 +808,23 @@ String InputEventMouseMotion::as_text() const {
|
||||
}
|
||||
|
||||
String InputEventMouseMotion::to_string() {
|
||||
MouseButton mouse_button_mask = get_button_mask();
|
||||
BitField<MouseButtonMask> mouse_button_mask = get_button_mask();
|
||||
String button_mask_string = itos((int64_t)mouse_button_mask);
|
||||
switch (mouse_button_mask) {
|
||||
case MouseButton::MASK_LEFT:
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1]));
|
||||
break;
|
||||
case MouseButton::MASK_MIDDLE:
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1]));
|
||||
break;
|
||||
case MouseButton::MASK_RIGHT:
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1]));
|
||||
break;
|
||||
case MouseButton::MASK_XBUTTON1:
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1]));
|
||||
break;
|
||||
case MouseButton::MASK_XBUTTON2:
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
if (mouse_button_mask.has_flag(MouseButtonMask::LEFT)) {
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1]));
|
||||
}
|
||||
if (mouse_button_mask.has_flag(MouseButtonMask::MIDDLE)) {
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1]));
|
||||
}
|
||||
if (mouse_button_mask.has_flag(MouseButtonMask::RIGHT)) {
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1]));
|
||||
}
|
||||
if (mouse_button_mask.has_flag(MouseButtonMask::MB_XBUTTON1)) {
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1]));
|
||||
}
|
||||
if (mouse_button_mask.has_flag(MouseButtonMask::MB_XBUTTON2)) {
|
||||
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1]));
|
||||
}
|
||||
|
||||
// Work around the fact vformat can only take 5 substitutions but 7 need to be passed.
|
||||
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
|
||||
void set_modifiers_from_event(const InputEventWithModifiers *event);
|
||||
|
||||
Key get_modifiers_mask() const;
|
||||
BitField<KeyModifierMask> get_modifiers_mask() const;
|
||||
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
class InputEventMouse : public InputEventWithModifiers {
|
||||
GDCLASS(InputEventMouse, InputEventWithModifiers);
|
||||
|
||||
MouseButton button_mask = MouseButton::NONE;
|
||||
BitField<MouseButtonMask> button_mask;
|
||||
|
||||
Vector2 pos;
|
||||
Vector2 global_pos;
|
||||
@@ -204,8 +204,8 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_button_mask(MouseButton p_mask);
|
||||
MouseButton get_button_mask() const;
|
||||
void set_button_mask(BitField<MouseButtonMask> p_mask);
|
||||
BitField<MouseButtonMask> get_button_mask() const;
|
||||
|
||||
void set_position(const Vector2 &p_pos);
|
||||
Vector2 get_position() const;
|
||||
|
||||
Reference in New Issue
Block a user