GetKeyState detects so many clicks but I only clicked once c++ - c++

I also tried to use Sleep because I saw in someone's code which was similar to mine but now it doesn't detect clicks I want it to detect
first I tested using the space key in my keyboard I thought it was only for space but when I tested using a character and mouse button I had the same issue so now I'm here to get help
here's my code:
void waitforspace()
{
bool strtd = false, stop = true, set = false;
std::chrono::steady_clock::time_point nw, thn;
std::thread t1;
while (true)
{
if ((GetKeyState(VK_RBUTTON) & 0x8000))
{
// I tried this to fix the repeating issue it worked but now most of the time my clicks doesn't get detected
if (!(GetKeyState(VK_RBUTTON) & 0x8000))
{
if (set)
{
nw = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> time_span = nw - thn;
set = false;
if (time_span.count() < 350.0)
{
std::cout << "Double click Detected!\n";
if (!strtd)
{
// Function I want to run if user clicked twice
t1 = std::thread(sendclicks, &stop);
strtd = true;
}
else
{
stop = false;
strtd = false;
}
}
}
else
{
std::cout << "One click Detected!\n";
thn = std::chrono::high_resolution_clock::now();
set = true;
}
}
}
}
}

Related

C++ boolean infinite loop

so I've got this code:
bool toggl = false;
while (!GetAsyncKeyState(VK_END)) {
if (GetAsyncKeyState(VK_INSERT)) {
if (toggl) {
toggl = false;
std::cout << "Off" << std::endl;
}
else {
toggl = true;
std::cout << "On" << std::endl;
}
}
}
The problem is whenever I click insert it just creates a infinite loop changing from false to true. When I use break my whole window just closes.
Any help appreciated.
Thanks,
Ossie
From the documentation for GetAsyncKeyState: "If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState."
hi lo
1000 0000 0000 0001
^ ^
| |
| pressed since last call
key down (0 for up)
For the infinite loop you only need to have the key state be non-zero. Better tests...
0 != (GetAsyncKeyState(VK_INSERT) & 1) // pressed since last call
0 != (GetAsyncKeyState(VK_INSERT) & 0x8000) // key down
The same documentation warns about use of this last bit for mouse clicks and when other processes are using GetAsyncKeyState at the same time. Worth reading.
Current URL to documentation: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
The problem is that when insert is tapped, your program will have looped on GetAsyncKeyState 20 or 30 times. And then your toggl flag is getting flipped each time. Hence, a new print statement.
I suspect this is what you really want:
bool toggl = false;
while (!GetAsyncKeyState(VK_END)) {
bool isInsertDown = (GetAsyncKeyState(VK_INSERT) != 0);
if (toggl && !isInsertDown)
{
toggl = false;
std::cout << "Off" << std::endl;
}
else if (!toggl && isInsertDown)
{
toggl = true;
std::cout << "On" << std::endl;
}
}
The above will flip the togl state to true when the insert key is down, and set it back to false when you lift your finger off the key.
But if you want to have toggl state changed on individual key presses. That is, first insert tap sets toggl to true and the next key press sets it back to false, then you'll need another variable. Hence:
bool toggl = false;
bool lastWasDown = false;
while (!GetAsyncKeyState(VK_END)) {
bool isInsertDown = GetAsyncKeyState(VK_INSERT) != 0;
if (isInsertDown == lastWasDown) {
continue;
}
if (isInsertDown && !toggl) {
toggl = true;
std::cout << "On" << std::endl;
}
else if (isInsertDown && toggl) {
toggl = false;
std::cout << "Off" << std::endl;
}
lastWasDown = isInsertDown;
}

Lowering CPU on MIDI playback thread

The function below is run on an std::thread that is detached. The code itself is written using the JUCE API (Hence Array<> object & MidiMessage).
void triggerMidiMessages(Array<Array<MidiMessage>> messageBundle)
{
//for each group of messages (bar) within the bundle
for(int bar = 0; bar < messageBundle.size(); bar ++)
{
//store our message from the bundle for playback
Array<MidiMessage> messages;
messages.clear();
messages = messageBundle[bar];
//intialise start time
double timestart = Time::getMillisecondCounterHiRes();
//for each midi inside a single "gene"
for(int i = 0; i <= messages.size();)
{
double elapsedTime = Time::getMillisecondCounterHiRes() - timestart;
//output message whens appropriate
if(elapsedTime > messages[i].getTimeStamp())
{
//output this message
masterMidiOutput->sendMessageNow(messages[i]);
//increment through the array
i++;
}
}
}
}
I need the midi messages to be output in real time but without having to run through the loop condition so much that the CPU runs super hot.
Any ideas? I'm stuck for how to playback the messages in such an order that doesn't require constant checking with a timer.
Thanks in advance.
//=====================================================================
update trying to sleep the thread...
void triggerMidiMessages(Array<Array<MidiMessage>> messageBundle)
{
//for each group of messages (bar) within a bundle
for(int bar = 0; bar < messageBundle.size(); bar ++)
{
//store our message from the bundle for playback
Array<MidiMessage> messages;
messages.clear();
messages = messageBundle[bar];
}
//intialise start time
double previousTimeStamp = 0;
//for each midi inside a single "gene"
for(int i = 0; i <= messages.size();)
{
//fire off all note on messages
while(messages[i].isNoteOn())
{
masterMidiOutput->sendMessageNow(messages[i]);
i++; //increment to the next
}
//fire off all note off messages
while(!messages[i].isNoteOn())
{
masterMidiOutput->sendMessageNow(messages[i]);
i++; // do the next one
//if the next message is back to a note on command
if(messages[i+1].isNoteOn() == true)
{
//sleep for x amount of time
int sleepTime = messages[i].getTimeStamp() - previousTimeStamp;
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
previousTimeStamp = messages[i].getTimeStamp();
}
}
}
}
}
To stop the build up within the thread it is better to turn on and off a timer object and trigger each message one by one.
Broadcast messages (Action Broadcaster )can then be used to keep track of the index.
Here is some example code to give the general idea :
MIDIThing::MIDIThing ()
{
startTimer(1); //start a timer
}
void MIDIThing::start ()
{
playstate = 1;
startTime = Time::getCurrentTime().toMilliseconds();
}
void MIDIThing::timerCallback()
{
if (playstate == 1) {
Time::getMillisecondCounterHiRes();
int64 target;
if (Time::getCurrentTime().toMilliseconds() > target) {
//fire off the message
}
//ended (possibly on a condition)
ActionBroadcaster::sendActionMessage(FINISHED_PLAYBACK);
}
}

Time lapse code in C++

I had to create timelapse function to wait for X amount of time in a loop.
The following code checks the boolean value of m_abortTimeLapseThread but after running for an hour I noticed the execution time of this code created 10 seconds delay. Is there a way to check m_abortTimeLapseThread as frequently as possible and wait for X amount of time in the function without the kind of delay I observed ?
void Acquisition::TimeLapseCount() {
int max10msWaitTimes = m_timeLapseInMs / 10;
while (true) {
m_timeLapseImageSaved = true;
for (int i = 0; i < max10msWaitTimes; i++)
{
if (m_abortTimeLapseThread) {
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
}
Thanks,
You could measure total time elapsed.
void Acquisition::TimeLapseCount() {
auto waitUntil = std::chrono::system_clock::now() + std::chrono::milliseconds(m_timeLapseInMs);
while (true) {
m_timeLapseImageSaved = true;
while (waitUntil > std::chrono::system_clock::now())
{
if (m_abortTimeLapseThread) {
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
waitUntil += std::chrono::milliseconds(m_timeLapseInMs);
}
}

Adding a delay between key pressing

I am using GetAsyncKeyState() to get the input every frame for a game that I'm making.
I want to move one x at each press, but not every frame, there has to be a delay. I currently I am doing this by having a cool down each time you press a key.
Here are some parts of my CoolDown class:
bool test(bool asumedStatus)
{
if(asumedStatus == status)
{
return true;
} else
{
return false;
}
}
void go()
{
if(currentCount == runFor)
{
status = OFF_COOLDOWN;
} else
{
currentCount++;
}
}
void start()
{
currentCount = 0;
status = ON_COOLDOWN;
}
controls gets called every frame to get the user input
void controls()
{
if(test(OFF_COOLDOWN))
{
if(KEY_L && !KEY_R && !KEY_U && !KEY_D)
{
left();
print();
cd.start();
}
else if(KEY_R && !KEY_L && !KEY_D && !KEY_U)
{
right();
print();
cd.start();
} else if(KEY_U && !KEY_L && !KEY_D && !KEY_R)
{
up();
print();
cd.start();
} else if(KEY_D && !KEY_L && !KEY_R && !KEY_U)
{
down();
print();
cd.start();
}
} else
{
cd.go();
}
}
Unfortunately, this does not work, the delay isn't there. Nothing changed.
Does someone have any ideas how I can accomplish this?
Here's how I would do it:
I use time to indicate frames, or ticks of the game.
I would make 2 variables:
startTime - Time point when the delay started
currentTime - Current time
Now, every tick, I'll update currentTime (by 1).
By taking the difference between those variables, you get the elapsed time since the start of the delay.
If the difference is greater than delay, then I have to reset the variables, to start all over again. So, setting startTime to currentTime, and setting currentTime to 0.
If the difference is less than delay, do nothing, because the delay isn't "done".
Something like:
startTime = 0;
currentTime = 0;
delay = 2000; //In frames/ticks
//Called every frame/tick
void update() {
++currentTime; //Update time
if (currentTime - startTime > delay) {
//Reset
startTime = currentTime;
currentTime = 0;
//Update whatever requires a delay
}
}

c++ process does not stop

There is something wrong in the code but I do not understand why.
I think one of the reason could be the threads that I used in the code.
The code looks like this.
in main.cpp
vector<thread> t;
vector<future<myClass>> futures;
vector<myClass> chV;
for(int i = 0; i < NumberOfThreads; i++) // NumberOfThreads are 2 here
{
promise<myClass> promises;
futures.push_back(promises.get_future());
t.push_back(thread(MyFunction ,i, PointsNumberInThreads , pointList, std::move(promises)));
}
for_each(t.begin(), t.end(), std::mem_fn(&std::thread::join));
for(int i = 0; i < futures.size(); i++ )
{
// futures.at(i).get().fOut(i); // <-- if I comment out then it gives error. but why?
chV.push_back(futures.at(i).get());
}
myClass c1 = chV.at(0);
myClass c2 = chV.at(1);
cout << "merge start" << endl; // <-- it prints out
c1.Merge(c2);
cout << "merge end" << endl; // <-- does not print out this message. so I have to kill the process
the Merge function in the myClass.cpp I have these sentences at the bottom of the function.
int aSt,aMid,aEnd;
int bSt,bMid,bEnd;
aSt = 0, aEnd = upperV.size(), aMid = (aEnd + aSt)/2;
bSt = 0, bEnd = b.upperV.size(), bMid = (bEnd + bSt)/2;
Point aPoint, bPoint, aPrev, aNext, bPrev, bNext;
aPoint = upperV.at(aMid);
aPrev = upperV.at(aMid-1);
aNext = upperV.at(aMid+1);
bPoint = b.upperV.at(bMid);
bPrev = b.upperV.at(bMid-1);
bNext = b.upperV.at(bMid+1);
bool done = true;
while(done)
{
done = false;
if(orientation(aPoint,bPoint,bPrev) > 0)
{
bEnd = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(aPoint,bPoint,bNext) > 0)
{
bSt = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(bPoint,aPoint,aPrev) < 0)
{
aEnd = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
if(orientation(bPoint,aPoint,aNext) < 0)
{
aSt = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
}
cout << "aPoint = (" << aPoint.x << " , " << aPoint.y << ")" << endl;
cout << "bPoint = (" << bPoint.x << " , " << bPoint.y << ")" << endl;
and they are printed but as I mentioned the process seems to keep running in somewhere.
This is the section of code that I think you should be concerned with. This may
not be why your code is continuing execution as you have stated in your problem, but from the code that you did provide to us; I still think this is an issue that should be addressed.
bool done = true;
while(done)
{
done = false;
if(orientation(aPoint,bPoint,bPrev) > 0)
{
bEnd = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(aPoint,bPoint,bNext) > 0)
{
bSt = bMid;
bMid = (bEnd + bSt)/2;
bPoint = b.upperV.at(bMid);
done = true;
}
if(orientation(bPoint,aPoint,aPrev) < 0)
{
aEnd = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
if(orientation(bPoint,aPoint,aNext) < 0)
{
aSt = aMid;
aMid = (aEnd + aSt)/2;
aPoint = upperV.at(aMid);
done = true;
}
}
You are initially setting this to be true. You are then going into your while loop and are setting it to false. All of your if statements set it back to true. So if any of these conditions are met depending on what orientation() returns then you are not going to break out of this while loop. It may seem to be illogical at first, but I learned over time that a good way to do while loops is in this structure.
bool done = false;
while ( !done ) {
// terminating case - I usually almost always check for this first!
if ( done ) {
break;
}
// Do work here and one or more cases could trip done to be equal to true
// within a if... else if ... else statement or within a series of if satements
// or none of them can, but if they don't then it must be set at the end of the while loop.
// Any one of these or all of them could set done = true and if they don't
// then you should set done = true at the end of the while loop since
// if none of these conditions are met, it will execute the assignment
// before it begins to loop.
if ( some condidition ) {
// Do this
} else if ( some other condidition ) {
// Do this instead
} else {
// Then do this
}
// Or this: Any of these could trip done = true or none of them
// and once again if none of them do, it should be the last thing done
// before the ending brace to your while loop.
if ( this ) {
// Do Work;
}
if ( this ) {
// Do Work;
}
// etc.
// Set this last if none of the if statements trip done to be true;
// otherwise if one or more does trip done, then you can omit this line.
// Note: If none of the if statements trip this flag and you trip it here
// in this section, this loop will occur only one time.
done = true;
}