Skip to content

Commit

Permalink
replace criitical_sections with mutexes
Browse files Browse the repository at this point in the history
  • Loading branch information
theyareonit committed Aug 13, 2024
1 parent 8ce58f2 commit 8c732c3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 67 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v1.1.22

* Potentially improve performance

# v1.1.21

* Fix an exploit that could allow you to double jump
Expand Down
11 changes: 7 additions & 4 deletions src/includes.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include <algorithm>
#include <queue>
#include <mutex>

#include <Geode/Geode.hpp>

using namespace geode::prelude;
Expand Down Expand Up @@ -39,13 +42,13 @@ struct Step {

extern std::queue<struct InputEvent> inputQueue;

extern std::unordered_set<size_t> inputBinds[6];
extern std::array<std::unordered_set<size_t>, 6> inputBinds;
extern std::unordered_set<USHORT> heldInputs;

extern CRITICAL_SECTION inputQueueLock;
extern CRITICAL_SECTION keybindsLock;
extern std::mutex inputQueueLock;
extern std::mutex keybindsLock;

extern bool enableRightClick;
extern std::atomic<bool> enableRightClick;
extern bool threadPriority;

void inputThread();
45 changes: 23 additions & 22 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

std::queue<struct InputEvent> inputQueue;

std::unordered_set<size_t> inputBinds[6];
std::array<std::unordered_set<size_t>, 6> inputBinds;
std::unordered_set<USHORT> heldInputs;

CRITICAL_SECTION inputQueueLock;
CRITICAL_SECTION keybindsLock;
std::mutex inputQueueLock;
std::mutex keybindsLock;

bool enableRightClick;
std::atomic<bool> enableRightClick;
bool threadPriority;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
Expand Down Expand Up @@ -50,40 +50,40 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
bool shouldEmplace = true;
player = Player1;

EnterCriticalSection(&keybindsLock);
std::array<std::unordered_set<size_t>, 6> binds;
{
std::lock_guard lock(keybindsLock);
binds = inputBinds;
}

if (inputBinds[p1Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (inputBinds[p1Left].contains(vkey)) inputType = PlayerButton::Left;
else if (inputBinds[p1Right].contains(vkey)) inputType = PlayerButton::Right;
if (binds[p1Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (binds[p1Left].contains(vkey)) inputType = PlayerButton::Left;
else if (binds[p1Right].contains(vkey)) inputType = PlayerButton::Right;
else {
player = Player2;
if (inputBinds[p2Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (inputBinds[p2Left].contains(vkey)) inputType = PlayerButton::Left;
else if (inputBinds[p2Right].contains(vkey)) inputType = PlayerButton::Right;
if (binds[p2Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (binds[p2Left].contains(vkey)) inputType = PlayerButton::Left;
else if (binds[p2Right].contains(vkey)) inputType = PlayerButton::Right;
else shouldEmplace = false;
}
if (!inputState) heldInputs.emplace(vkey);

LeaveCriticalSection(&keybindsLock);
if (!inputState) heldInputs.emplace(vkey);
if (!shouldEmplace) return 0;

if (!shouldEmplace) return 0; // has to be done outside of the critical section
break;
}
case RIM_TYPEMOUSE: {
USHORT flags = raw->data.mouse.usButtonFlags;
bool shouldEmplace = true;

player = Player1;
inputType = PlayerButton::Jump;

EnterCriticalSection(&keybindsLock);
bool rc = enableRightClick;
LeaveCriticalSection(&keybindsLock);

if (flags & RI_MOUSE_BUTTON_1_DOWN) inputState = Press;
else if (flags & RI_MOUSE_BUTTON_1_UP) inputState = Release;
else {
player = Player2;
if (!rc) return 0;
if (!enableRightClick.load()) return 0;
if (flags & RI_MOUSE_BUTTON_2_DOWN) inputState = Press;
else if (flags & RI_MOUSE_BUTTON_2_UP) inputState = Release;
else return 0;
Expand All @@ -99,9 +99,10 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return DefWindowProcA(hwnd, uMsg, wParam, lParam);
}

EnterCriticalSection(&inputQueueLock);
inputQueue.emplace(InputEvent{ time, inputType, inputState, player });
LeaveCriticalSection(&inputQueueLock);
{
std::lock_guard lock(inputQueueLock);
inputQueue.emplace(InputEvent{ time, inputType, inputState, player });
}

return 0;
}
Expand Down
72 changes: 31 additions & 41 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "includes.hpp"

#include <queue>
#include <algorithm>
#include <limits>

#include <Geode/Geode.hpp>
Expand Down Expand Up @@ -48,31 +46,31 @@ void updateInputQueueAndTime(int stepCount) {
else {
nextInput = emptyInput;
lastFrameTime = lastPhysicsFrameTime;
std::queue<struct Step>().swap(stepQueue); // just in case
stepQueue = {}; // just in case

EnterCriticalSection(&inputQueueLock);
{
std::lock_guard lock(inputQueueLock);

if (lateCutoff) {
QueryPerformanceCounter(&currentFrameTime); // done within the critical section to prevent a race condition which could cause dropped inputs
inputQueueCopy = inputQueue;
std::queue<struct InputEvent>().swap(inputQueue);
}
else {
while (!inputQueue.empty() && inputQueue.front().time.QuadPart <= currentFrameTime.QuadPart) {
inputQueueCopy.push(inputQueue.front());
inputQueue.pop();
if (lateCutoff) {
QueryPerformanceCounter(&currentFrameTime);
inputQueueCopy = inputQueue;
inputQueue = {};
}
else {
while (!inputQueue.empty() && inputQueue.front().time.QuadPart <= currentFrameTime.QuadPart) {
inputQueueCopy.push(inputQueue.front());
inputQueue.pop();
}
}
}

LeaveCriticalSection(&inputQueueLock);

lastPhysicsFrameTime = currentFrameTime;

if (!firstFrame) skipUpdate = false;
else {
skipUpdate = true;
firstFrame = false;
if (!lateCutoff) std::queue<struct InputEvent>().swap(inputQueueCopy);
if (!lateCutoff) inputQueueCopy = {};
return;
}

Expand Down Expand Up @@ -126,32 +124,33 @@ Step updateDeltaFactorAndInput() {
}

void updateKeybinds() {
std::array<std::unordered_set<size_t>, 6> binds;
std::vector<geode::Ref<keybinds::Bind>> v;

EnterCriticalSection(&keybindsLock);

enableRightClick = Mod::get()->getSettingValue<bool>("right-click");
inputBinds->clear();
enableRightClick.store(Mod::get()->getSettingValue<bool>("right-click"));

v = keybinds::BindManager::get()->getBindsFor("robtop.geometry-dash/jump-p1");
for (int i = 0; i < v.size(); i++) inputBinds[p1Jump].emplace(v[i]->getHash());
for (int i = 0; i < v.size(); i++) binds[p1Jump].emplace(v[i]->getHash());

v = keybinds::BindManager::get()->getBindsFor("robtop.geometry-dash/move-left-p1");
for (int i = 0; i < v.size(); i++) inputBinds[p1Left].emplace(v[i]->getHash());
for (int i = 0; i < v.size(); i++) binds[p1Left].emplace(v[i]->getHash());

v = keybinds::BindManager::get()->getBindsFor("robtop.geometry-dash/move-right-p1");
for (int i = 0; i < v.size(); i++) inputBinds[p1Right].emplace(v[i]->getHash());
for (int i = 0; i < v.size(); i++) binds[p1Right].emplace(v[i]->getHash());

v = keybinds::BindManager::get()->getBindsFor("robtop.geometry-dash/jump-p2");
for (int i = 0; i < v.size(); i++) inputBinds[p2Jump].emplace(v[i]->getHash());
for (int i = 0; i < v.size(); i++) binds[p2Jump].emplace(v[i]->getHash());

v = keybinds::BindManager::get()->getBindsFor("robtop.geometry-dash/move-left-p2");
for (int i = 0; i < v.size(); i++) inputBinds[p2Left].emplace(v[i]->getHash());
for (int i = 0; i < v.size(); i++) binds[p2Left].emplace(v[i]->getHash());

v = keybinds::BindManager::get()->getBindsFor("robtop.geometry-dash/move-right-p2");
for (int i = 0; i < v.size(); i++) inputBinds[p2Right].emplace(v[i]->getHash());
for (int i = 0; i < v.size(); i++) binds[p2Right].emplace(v[i]->getHash());

LeaveCriticalSection(&keybindsLock);
{
std::lock_guard lock(keybindsLock);
inputBinds = binds;
}
}

void newResetCollisionLog(PlayerObject* p) { // inlined in 2.206...
Expand Down Expand Up @@ -188,11 +187,12 @@ class $modify(CCDirector) {
skipUpdate = true;
enableInput = true;

std::queue<struct InputEvent>().swap(inputQueueCopy);
inputQueueCopy = {};

EnterCriticalSection(&inputQueueLock);
std::queue<struct InputEvent>().swap(inputQueue);
LeaveCriticalSection(&inputQueueLock);
{
std::lock_guard lock(inputQueueLock);
inputQueue = {};
}
}

CCDirector::setDeltaTime(dTime);
Expand Down Expand Up @@ -377,16 +377,6 @@ void toggleMod(bool disable) {
}

$on_mod(Loaded) {
if (!InitializeCriticalSectionAndSpinCount(&inputQueueLock, 0x00040000)) {
log::error("Failed to initialize input queue lock");
return;
}

if (!InitializeCriticalSectionAndSpinCount(&keybindsLock, 0x00040000)) {
log::error("Failed to initialize keybind lock");
return;
}

toggleMod(Mod::get()->getSettingValue<bool>("soft-toggle"));
listenForSettingChanges("soft-toggle", toggleMod);

Expand Down

0 comments on commit 8c732c3

Please sign in to comment.