Optimized Button class. Added IsPressed and GetPressed methods.

This commit is contained in:
Arron David Nelson 2024-08-04 00:47:38 -07:00
parent 3970b8d402
commit 8d4420528a
14 changed files with 240 additions and 52 deletions

View File

@ -8,24 +8,30 @@ namespace ehs
class EHS_LIB_IO Button class EHS_LIB_IO Button
{ {
private: private:
Str_8 name;
UInt_32 hash; UInt_32 hash;
Str_8 name;
public: public:
Button(); Button();
Button(const Str_8& name); Button(Str_8 name);
Button(Button &&key) noexcept;
Button(const Button &key); Button(const Button &key);
Button &operator=(Button &&key) noexcept;
Button &operator=(const Button &key); Button &operator=(const Button &key);
bool operator==(const Button &key) const; bool operator==(const Button &key) const;
bool operator!=(const Button &key) const; bool operator!=(const Button &key) const;
UInt_32 GetHash() const;
Str_8 GetName() const; Str_8 GetName() const;
UInt_32 GetHash() const; bool IsValid() const;
}; };
} }

View File

@ -15,11 +15,15 @@ namespace ehs
Str_8 name; Str_8 name;
UInt_64 id; UInt_64 id;
Array<ButtonState> states; Array<ButtonState> states;
Button lastState;
float heldTime;
float activateTime;
bool active;
public: public:
HID(); HID();
HID(const UInt_8 type, Str_8 name, const UInt_64 id); HID(UInt_8 type, Str_8 name, UInt_64 id);
HID(HID&& hid) noexcept; HID(HID&& hid) noexcept;
@ -33,11 +37,11 @@ namespace ehs
bool operator!=(const HID& other) const; bool operator!=(const HID& other) const;
bool operator==(const UInt_64 otherId) const; bool operator==(UInt_64 otherId) const;
bool operator!=(const UInt_64 otherId) const; bool operator!=(UInt_64 otherId) const;
virtual void Poll(); virtual void Poll(float delta);
UInt_8 GetType() const; UInt_8 GetType() const;
@ -71,6 +75,10 @@ namespace ehs
const ButtonState* IsUp() const; const ButtonState* IsUp() const;
const ButtonState *IsPressed(const Button &button);
const ButtonState *GetPressed();
void ButtonDown(const Button& button); void ButtonDown(const Button& button);
void ButtonUp(const Button& button); void ButtonUp(const Button& button);
@ -87,5 +95,11 @@ namespace ehs
bool AddState(const ButtonState& state); bool AddState(const ButtonState& state);
ButtonState* GetState(const Button& button); ButtonState* GetState(const Button& button);
bool TickHoldTime(float delta);
void ResetTime();
void TickActivateTime(float delta);
}; };
} }

View File

@ -10,6 +10,8 @@ namespace ehs
private: private:
UInt_64 hashId; UInt_64 hashId;
Str_8 id; Str_8 id;
UInt_64 start;
UInt_64 delta;
protected: protected:
Array<HID*> devices; Array<HID*> devices;
@ -29,9 +31,9 @@ namespace ehs
InputHandler& operator=(const InputHandler& ih); InputHandler& operator=(const InputHandler& ih);
bool operator==(const UInt_64 otherHashId); bool operator==(const UInt_64 otherHashId) const;
bool operator!=(const UInt_64 otherHashId); bool operator!=(const UInt_64 otherHashId) const;
virtual bool Initialize(); virtual bool Initialize();

View File

@ -23,7 +23,7 @@ namespace ehs
Keyboard& operator=(const Keyboard& hid); Keyboard& operator=(const Keyboard& hid);
void Poll() override; void Poll(float delta) override;
Keyboard* Clone() const override; Keyboard* Clone() const override;

View File

@ -19,7 +19,7 @@ namespace ehs
public: public:
Mouse(); Mouse();
Mouse(Str_8 name, const UInt_64 id); Mouse(Str_8 name, UInt_64 id);
Mouse(Mouse&& hid) noexcept = default; Mouse(Mouse&& hid) noexcept = default;
@ -29,7 +29,7 @@ namespace ehs
Mouse& operator=(const Mouse& hid); Mouse& operator=(const Mouse& hid);
void Poll() override; void Poll(float delta) override;
void SetDelta(const Vec2_s32& newDelta); void SetDelta(const Vec2_s32& newDelta);

View File

@ -9,5 +9,7 @@ namespace ehs
{ {
public: public:
static void OpenURI(const Str_8& uri); static void OpenURI(const Str_8& uri);
static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);
}; };
} }

View File

@ -9,5 +9,7 @@ namespace ehs
{ {
public: public:
static void OpenURI(const Str_8& uri); static void OpenURI(const Str_8& uri);
static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);
}; };
} }

View File

@ -7,14 +7,33 @@ namespace ehs
{ {
} }
Button::Button(const Str_8& name) Button::Button(Str_8 name)
: name(name), hash(name.Hash_32()) : hash(name.Hash_32()), name((Str_8 &&)name)
{ {
} }
Button::Button(const Button& key) Button::Button(Button &&key) noexcept
: name(key.name), hash(key.hash) : hash(key.hash), name((Str_8 &&)key.name)
{ {
key.hash = 0;
}
Button::Button(const Button &key)
: hash(key.hash), name(key.name)
{
}
Button & Button::operator=(Button &&key) noexcept
{
if (this == &key)
return *this;
hash = key.hash;
name = (Str_8 &&)key.name;
key.hash = 0;
return *this;
} }
Button &Button::operator=(const Button &key) Button &Button::operator=(const Button &key)
@ -22,8 +41,8 @@ namespace ehs
if (this == &key) if (this == &key)
return *this; return *this;
name = key.name;
hash = key.hash; hash = key.hash;
name = key.name;
return *this; return *this;
} }
@ -38,12 +57,17 @@ namespace ehs
return key.hash != hash; return key.hash != hash;
} }
UInt_32 Button::GetHash() const
{
return hash;
}
Str_8 Button::GetName() const Str_8 Button::GetName() const
{ {
return name; return name;
} }
UInt_32 Button::GetHash() const bool Button::IsValid() const
{ {
return hash; return hash;
} }

View File

@ -1,26 +1,39 @@
#include "ehs/io/hid/HID.h" #include "ehs/io/hid/HID.h"
#include "ehs/Log.h"
#include "ehs/Math.h"
#include "ehs/io/hid/Keyboard.h"
namespace ehs namespace ehs
{ {
HID::HID() HID::HID()
: type(EHS_HID_UNKNOWN), id(0) : type(EHS_HID_UNKNOWN), hashName(0), id(0), heldTime(0.0), activateTime(0.0f), active(false)
{ {
} }
HID::HID(const UInt_8 type, Str_8 name, const UInt_64 id) HID::HID(const UInt_8 type, Str_8 name, const UInt_64 id)
: type(type), name((Str_8&&)name), id(id) : type(type), hashName(name.Hash_64()), name((Str_8 &&)name), id(id), heldTime(0.0f), activateTime(0.0f),
active(false)
{ {
} }
HID::HID(HID&& hid) noexcept HID::HID(HID&& hid) noexcept
: type(hid.type), name((Str_8&&)hid.name), id(hid.id), states((Array<ButtonState>&&)hid.states) : type(hid.type), hashName(hid.hashName), name((Str_8&&)hid.name), id(hid.id),
states((Array<ButtonState> &&)hid.states), lastState((Button &&)hid.lastState), heldTime(hid.heldTime),
activateTime(hid.activateTime), active(hid.active)
{ {
hid.type = EHS_HID_UNKNOWN; hid.type = EHS_HID_UNKNOWN;
hid.hashName = 0;
hid.id = 0; hid.id = 0;
hid.lastState = {};
hid.heldTime = 0.0f;
hid.activateTime = 0.0f;
hid.active = false;
} }
HID::HID(const HID& hid) HID::HID(const HID& hid)
: type(hid.type), name(hid.name), id(hid.id), states(hid.states) : type(hid.type), hashName(hid.hashName), name(hid.name), id(hid.id), states(hid.states), heldTime(0.0f),
activateTime(0.0f), active(false)
{ {
} }
@ -30,12 +43,22 @@ namespace ehs
return *this; return *this;
type = hid.type; type = hid.type;
hashName = hid.hashName;
name = (Str_8&&)hid.name; name = (Str_8&&)hid.name;
id = hid.id; id = hid.id;
states = (Array<ButtonState> &&)hid.states; states = (Array<ButtonState> &&)hid.states;
lastState = (Button &&)hid.lastState;
heldTime = hid.heldTime;
activateTime = hid.activateTime;
active = hid.active;
hid.type = EHS_HID_UNKNOWN; hid.type = EHS_HID_UNKNOWN;
hid.hashName = 0;
hid.id = 0; hid.id = 0;
hid.lastState = {};
hid.heldTime = 0.0f;
hid.activateTime = 0.0f;
hid.active = false;
return *this; return *this;
} }
@ -46,9 +69,14 @@ namespace ehs
return *this; return *this;
type = hid.type; type = hid.type;
hashName = hid.hashName;
name = hid.name; name = hid.name;
id = hid.id; id = hid.id;
states = hid.states; states = hid.states;
lastState = {};
heldTime = 0.0f;
activateTime = 0.0f;
active = false;
return *this; return *this;
} }
@ -73,16 +101,30 @@ namespace ehs
return id != otherId; return id != otherId;
} }
void HID::Poll() void HID::Poll(const float delta)
{ {
for (UInt_64 i = 0; i < states.Size(); ++i) for (UInt_64 i = 0; i < states.Size(); ++i)
{ {
if (states[i].IsPressed()) if (states[i].IsPressed())
{ {
if (states[i].GetState() == State::RELEASED) if (states[i].GetState() == State::RELEASED)
{
states[i].SetState(State::TOUCHED); states[i].SetState(State::TOUCHED);
lastState = states[i].GetButton();
ResetTime();
active = true;
}
else else
{
states[i].SetState(State::PRESSED); states[i].SetState(State::PRESSED);
if (lastState == states[i].GetButton())
{
if (TickHoldTime(delta))
TickActivateTime(delta);
}
}
} }
else else
{ {
@ -90,6 +132,13 @@ namespace ehs
states[i].SetState(State::JUST_RELEASED); states[i].SetState(State::JUST_RELEASED);
else else
states[i].SetState(State::RELEASED); states[i].SetState(State::RELEASED);
if (lastState == states[i].GetButton())
{
lastState = {};
ResetTime();
active = false;
}
} }
} }
} }
@ -149,7 +198,7 @@ namespace ehs
Vector<const ButtonState*> result(0, states.Size() + 1); Vector<const ButtonState*> result(0, states.Size() + 1);
for (UInt_64 i = 0; i < states.Size(); i++) for (UInt_64 i = 0; i < states.Size(); i++)
if (states[i] == State::PRESSED || states[i] == State::TOUCHED) if (states[i] == State::PRESSED)
result.Push(&states[i]); result.Push(&states[i]);
return result; return result;
@ -158,7 +207,7 @@ namespace ehs
const ButtonState* HID::IsDown(const Button& button) const const ButtonState* HID::IsDown(const Button& button) const
{ {
const ButtonState* state = GetState(button); const ButtonState* state = GetState(button);
if (!state || (*state != State::PRESSED && *state != State::TOUCHED)) if (!state || (*state != State::PRESSED))
return nullptr; return nullptr;
return state; return state;
@ -167,7 +216,7 @@ namespace ehs
const ButtonState* HID::IsDown() const const ButtonState* HID::IsDown() const
{ {
for (UInt_64 i = 0; i < states.Size(); i++) for (UInt_64 i = 0; i < states.Size(); i++)
if (states[i] == State::PRESSED || states[i] == State::TOUCHED) if (states[i] == State::PRESSED)
return &states[i]; return &states[i];
return nullptr; return nullptr;
@ -231,6 +280,22 @@ namespace ehs
return nullptr; return nullptr;
} }
const ButtonState *HID::IsPressed(const Button &button)
{
if (active && lastState == button)
return GetState(lastState);
return nullptr;
}
const ButtonState *HID::GetPressed()
{
if (active)
return GetState(lastState);
return nullptr;
}
void HID::ButtonDown(const Button& button) void HID::ButtonDown(const Button& button)
{ {
if (ButtonState* state = GetState(button); state) if (ButtonState* state = GetState(button); state)
@ -249,6 +314,9 @@ namespace ehs
const ButtonState* HID::GetState(const Button& button) const const ButtonState* HID::GetState(const Button& button) const
{ {
if (!button.IsValid())
return nullptr;
for (UInt_64 i = 0; i < states.Size(); ++i) for (UInt_64 i = 0; i < states.Size(); ++i)
if (states[i] == button) if (states[i] == button)
return &states[i]; return &states[i];
@ -287,10 +355,42 @@ namespace ehs
ButtonState* HID::GetState(const Button& button) ButtonState* HID::GetState(const Button& button)
{ {
if (!button.IsValid())
return nullptr;
for (UInt_64 i = 0; i < states.Size(); i++) for (UInt_64 i = 0; i < states.Size(); i++)
if (states[i].GetButton() == button) if (states[i].GetButton() == button)
return &states[i]; return &states[i];
return nullptr; return nullptr;
} }
bool HID::TickHoldTime(const float delta)
{
if ((heldTime += delta) > 0.5f)
return true;
active = false;
return false;
}
void HID::ResetTime()
{
heldTime = 0.0f;
activateTime = 0.0f;
}
void HID::TickActivateTime(const float delta)
{
if ((activateTime += delta) > 0.075f)
{
activateTime = ehs::Math::Mod(activateTime, 0.075f);
active = true;
}
else
{
active = false;
}
}
} }

View File

@ -1,5 +1,7 @@
#include "ehs/io/hid/InputHandler.h" #include "ehs/io/hid/InputHandler.h"
#include "ehs/system/CPU.h"
namespace ehs namespace ehs
{ {
InputHandler::~InputHandler() InputHandler::~InputHandler()
@ -9,23 +11,24 @@ namespace ehs
} }
InputHandler::InputHandler() InputHandler::InputHandler()
: hashId(0) : hashId(0), start(0)
{ {
} }
InputHandler::InputHandler(Str_8 id) InputHandler::InputHandler(Str_8 id)
: hashId(id.Hash_64()), id((Str_8&&)id) : hashId(id.Hash_64()), id((Str_8&&)id), start(CPU::GetTSC())
{ {
} }
InputHandler::InputHandler(InputHandler&& ih) noexcept InputHandler::InputHandler(InputHandler&& ih) noexcept
: hashId(ih.hashId), id((Str_8&&)ih.id), devices((Array<HID*>&&)ih.devices) : hashId(ih.hashId), id((Str_8&&)ih.id), devices((Array<HID*>&&)ih.devices), start(ih.start)
{ {
ih.hashId = 0; ih.hashId = 0;
ih.start = 0;
} }
InputHandler::InputHandler(const InputHandler& ih) InputHandler::InputHandler(const InputHandler& ih)
: hashId(ih.hashId), id(ih.id), devices(ih.devices.Size()) : hashId(ih.hashId), id(ih.id), devices(ih.devices.Size()), start(ih.start)
{ {
for (UInt_64 i = 0; i < devices.Size(); i++) for (UInt_64 i = 0; i < devices.Size(); i++)
devices[i] = ih.devices[i]->Clone(); devices[i] = ih.devices[i]->Clone();
@ -39,8 +42,10 @@ namespace ehs
hashId = ih.hashId; hashId = ih.hashId;
id = (Str_8&&)ih.id; id = (Str_8&&)ih.id;
devices = (Array<HID*>&&)ih.devices; devices = (Array<HID*>&&)ih.devices;
start = ih.start;
ih.hashId = 0; ih.hashId = 0;
ih.start = 0;
return *this; return *this;
} }
@ -56,6 +61,7 @@ namespace ehs
hashId = ih.hashId; hashId = ih.hashId;
id = ih.id; id = ih.id;
devices = Array<HID*>(ih.devices.Size()); devices = Array<HID*>(ih.devices.Size());
start = ih.start;
for (UInt_64 i = 0; i < devices.Size(); i++) for (UInt_64 i = 0; i < devices.Size(); i++)
devices[i] = ih.devices[i]->Clone(); devices[i] = ih.devices[i]->Clone();
@ -63,12 +69,12 @@ namespace ehs
return *this; return *this;
} }
bool InputHandler::operator==(const UInt_64 otherHashId) bool InputHandler::operator==(const UInt_64 otherHashId) const
{ {
return hashId == otherHashId; return hashId == otherHashId;
} }
bool InputHandler::operator!=(const UInt_64 otherHashId) bool InputHandler::operator!=(const UInt_64 otherHashId) const
{ {
return hashId != otherHashId; return hashId != otherHashId;
} }
@ -96,8 +102,14 @@ namespace ehs
void InputHandler::Poll() void InputHandler::Poll()
{ {
static UInt_64 freq = CPU::GetTSC_Freq();
const UInt_64 newTSC = CPU::GetTSC();
delta = newTSC - start;
start = newTSC;
for (UInt_64 i = 0; i < devices.Size(); i++) for (UInt_64 i = 0; i < devices.Size(); i++)
devices[i]->Poll(); devices[i]->Poll((float)delta / (float)freq);
} }
UInt_64 InputHandler::GetHashId() const UInt_64 InputHandler::GetHashId() const

View File

@ -26,9 +26,9 @@ namespace ehs
return *this; return *this;
} }
void Keyboard::Poll() void Keyboard::Poll(const float delta)
{ {
HID::Poll(); HID::Poll(delta);
} }
Keyboard* Keyboard::Clone() const Keyboard* Keyboard::Clone() const

View File

@ -28,11 +28,11 @@ namespace ehs
return *this; return *this;
} }
void Mouse::Poll() void Mouse::Poll(const float delta)
{ {
delta = {}; this->delta = {};
HID::Poll(); HID::Poll(delta);
} }
void Mouse::SetDelta(const Vec2_s32& newDelta) void Mouse::SetDelta(const Vec2_s32& newDelta)

View File

@ -5,4 +5,9 @@ namespace ehs
void BaseSystem::OpenURI(const Str_8& uri) void BaseSystem::OpenURI(const Str_8& uri)
{ {
} }
Str_8 BaseSystem::OpenFileDialog(const Str_8 &dir, const Str_8 &filters)
{
return {};
}
} }

View File

@ -1,4 +1,7 @@
#include "ehs/system/System_LNX.h" #include "ehs/system/System_LNX.h"
#include <cstdio>
#include "ehs/system/Thread.h" #include "ehs/system/Thread.h"
#include "ehs/Log.h" #include "ehs/Log.h"
@ -19,4 +22,22 @@ namespace ehs
xdg.Start(XDG_Thread, (void*)&uri); xdg.Start(XDG_Thread, (void*)&uri);
xdg.Detach(); xdg.Detach();
} }
Str_8 System::OpenFileDialog(const Str_8 &dir, const Str_8 &filters)
{
FILE *file = popen("kdialog --getopenfilename " + dir + " \'" + filters + "\'", "r");
Str_8 result;
char array[128];
while(fgets(array, sizeof(array), file))
result.Push(array);
pclose(file);
if (result.Size())
result.Pop();
return result;
}
} }