How to run an infinite loop? - c++

I want to run some code over and over again basically forever, but I don't want my computer to run out of memory or something like that. So I was wondering how i could do that in c++? I did this.
for (int i = 0; i <= 2; i++) {
if (i == 1) {i = 0;}
//My code here
}
I was wondering if this would do something bad to my computer?

while(true)
{
//Your code here
}

If you prefer the for syntax:
for ( ; ; ) {
// do stuff.
}
An infinite loop will not cause your computer to run out of memory if you aren't allocating memory without freeing them.

There are a few common ways of writing an infinite loop.
for (;;) {
// do something over an over again
}
while (true) {
// do something over an over again
}
By itself, an infinite loop doesn't cause the program to run out of memory. But if you allocate memory and forget to deallocate it, that would cause memory leak. In light that, the following code would be alright:
YourClass* p;
for (;;) {
p = new YourClass(); // every time the loop runs, a new instance of the class is created
// [do something useful with the object]
delete p; // clean-up: deallocate the object.
}
But this would cause a memory leak:
YourClass* p;
for (;;) {
p = new YourClass(); // every time the loop runs, a new instance of the class is created
// [do something useful with the object]
// oups... forgot to deallocate the object.
}

Infinite Loops are great if you know how to manage them. Even with an infinite loop you would still want a possible exit condition. If you are designing infinite loops as to where there are no possible exits out of the loop based on its dataset, the safest thing to do is to keep track of the instance of your application object and its current state and when its state changes to exit, then any infinite loop running across any thread can be tested against this and will automatically exit when available to do so to prevent your computer from hanging to where you would need to do a hard reset or shutdown. Just make sure that all of your memory will be cleaned up as this event is triggered. Now if you have multiple threads running either in parallel or asynchronous and they are managed by a queue or event trigger list then it still may take time for every loop to exit depending on which loops you designate to be in a CRITICAL_SECTION.
class Application {
public:
enum ApplicationState {
APPLICATION_RUNNING = 0,
APPLICATION_PAUSED, // Out of Focus or Paused If In A Timed Situation
APPLICATION_EXIT,
};
private:
// Member Variables Such As Window Handle, Time Etc.,
ApplicationState m_state;
public:
Application();
// virtual ~Application(); // Default Okay - Use Virtual If Using Inheritance
ApplicationState getState() const { return m_state; }
bool start() { m_sate = APPLICATION_RUNNING; return true; }
bool pause() { m_state = APPLICATION_PAUSED; return true; }
// resume may keep track of time if the application uses a timer.
// This is what makes it different than start() where the timer
// in start() would be initialized to 0. And the last time before
// paused was trigger would be saved, and then reset as new starting
// time for your timer or counter.
bool resume() { m_state = APPLICATION_RUNNING; return true; }
bool exit(); { m_state = APPLICATION_EXIT; return false; }
};
int main() {
Application app;
app.start();
// One Type Of Infinite Loop, with a safety net.
while ( !app.exit() ) {
// do some work
}
// Another Type Similar But Different
while ( app.getState() == Application::APPLICATION_RUNNING ) {
// do some work
}
// A Third Type
while ( true ) {
switch( app.getState() ) {
case Application::APPLICATION_RUNNING {
app.start(); // If Not Done Above Outside of Loop
// Do Some Work
break;
}
case Application::APPLICATION_PAUSE {
// Wait Till You Has Focus Or Continues
break;
}
case Application::APPLICATION_EXIT {
// Change The Application State
app.pause();
break;
}
default: {
// ErrorHandling Throw An Exception Etc.
}
} // switch
} while
return 0;
}
Some Of These Types of methods you may not necessarily see in the main.cpp.
You would see these types of loops within your application class that are done privately and invoked publicly so that your main.cpp would look cleaner as such:
main.cpp
#include "Application.h"
int main() {
try {
// Initialize Loggers, Settings, Process - Thread Blockers etc.
// Handle Input Arguements
// Give The Main Thread Application, Window Handle, Mutex etc, A Unique Name
const std::string strApplicationName( "My Application" );
Application app( strApplicationName );
app.start();
}
} catch( YourTypes& e ) {
// Print Errors To Either File Or Console
return RETURN_ERROR;
} catch ( ... ) { // Default Types
// Print Errors To Either File Or Console
return RETURN_ERROR;
}
return RETURN_OK; // return 0;
}
This way your main is clean and easy to follow and your loops are happening within your application class object. This way you can still have infinite loops running as long as the application is running. Now if you are writing drivers, file or memory monitors, malware or antivirus dlls or processes that run in windows background then you may not want this behavior, but since these processes run in the background of windows it is still safe to say yes if this process or executable goes out of scope and ends we still want to exit all loops safely and clean up all memory!
The Paradigm here is to safely and efficiently manage a well structured application. The reason I used this as an example is that when you get away from writing event driven or data driven types of applications and are working with any kind of game development this is an appropriate model to follow. The only difference instead of naming your class as Application, you would more than likely name it Game and have Game inherit from an Engine class. This way the code is re-usable to build and develop multiple games. It is generic enough to handle all graphics, sounds, fonts, rendering etc., and this Engine class will be abstract where this base class can not be instantiated on its own, you would have to create the Game class object as an inherited class that can be instantiated. You may also want to have the Engine class inherit from a Singleton class so that you can only ever have one instance of a Game : Engine object. The Game class would then be responsible for all of the assets being loaded, level designs being loaded, which fonts & sounds to be loaded, which animations to load, etc., things that are unique to this game. This makes it very modular. This setup would also require the Engine to construct multiple Manager type classes that rely heavily on templates.
This following is not my work, but is a project I've been working on and all credit goes to Marek A. Krzeminski, MASc at http://www.marekknows.com This excerpt shows the main.cpp file.
// Version: 1.0
// Copyright (c) 2012 by Marek A. Krzeminski, MASc
// Marek#MarekKnows.com
#include "stdafx.h"
#include "BuildConfig.h"
#include "Settings.h"
#include "BlockProcess.h"
#include "Logger.h"
#include "Utility.h"
#include "Game.h"
// ----------------------------------------------------------------------------
// _tmain()
// Main Entry Point Into Application
int _tmain( int iNumArguments, _TCHAR* pArgumentText[] ) {
using namespace vmk;
try {
// Test If Engine Is Supported By This Compiler
Utility::testPlatform();
Logger logger( "logger.txt" );
Settings settings;
// Prevent Starting Game Multiple Times At Once
BlockProcess processBlocker( settings.getNameAndVersion() );
if ( processBlocker.isBlocked() ) {
std::ostringstream strStream;
strStream << settings.getNameAndVersion() << " is already running in another window" << std::endl;
throw ExceptionHandler( strStream, false );
}
// Handle Input Arguments
bool bShowHelp = false;
for ( int i = 1; i < iNumArguments; ++i ) {
std::ostringstream strStream;
strStream << "Input Argument " << i << ": " << pArgumentText[i];
std::string strArgument( Utility::toLower( std::string( pArgumentText[i] ) ) );
if ( strArgument.compare( "/?" ) == 0 || strArgument.compare( "help" ) == 0 ) {
bShowHelp = true;
} else if ( strArgument.compare( "window" ) == 0 ) {
settings.setWindowDisplayMode( true );
} else if ( strArgument.compare( "debug_memory" ) == 0 ) {
settings.setDebugLogging( settings.getDebugLogging() | Settings::DEBUG_MEMORY );
} else if ( strArgument.compare( "seed" ) == 0 ) {
// Need Next Argument To Know Which Seed Value To Use
bool bError = false;
unsigned uSeedValue = 0;
if ( i + 1 < iNumArguments ) {
uSeedValue = Utility::convertToUnsigned( std::string( pArgumentText[i+1] ) );
if ( uSeedValue == 0 ) {
bError = true;
} else {
settings.setRandomNumberSeed( uSeedValue );
i++; // Move Argument Counter Past Seed Value
}
} else {
bError = true;
}
if ( bError ) {
// Missing Argument For Seed Value
std::cout << " <- Missing Seed Value After This Argument";
} else {
// Display Seed Value To Use
strStream << " " << uSeedValue;
}
} else {
strStream << " <- Unrecognized input argument";
}
Logger::log( strStream, Logger::TYPE_CONSOLE );
}
if ( bShowHelp ) {
std::ostringstream strStream;
strStream << std::endl
<< settings.getNameAndVersion() << " command line arguments:" << std::endl
<< " seed nnn | Supply seed value (nnn) to use in random number generator" << std::endl
<< " window | Run the program in a window rather then full screen" << std::endl
<< " debug_memory | Log extra messages when objects are allocated in memory" << std::endl
<< std::endl;
Logger::log( strStream, Logger::TYPE_CONSOLE );
} else {
// Run The Game Here
Game game;
game.start();
}
} catch( ExceptionHandler& e ) {
std::cout << "Exception Thrown: " << e.getMessage() << std::endl;
Utility::pressAnyKeyToQuit();
return RETURN_ERROR;
} catch( ... ) {
std::cout << __FUNCTION__ << " Caught Unknown Exception" << std::endl;
Utility::pressAnyKeyToQuit();
return RETURN_ERROR;
}
return RETURN_OK;
} // _tmain
As you can see there is no visible infinite while or for loop visible here since this type of algorithm is nested deep within the Game - Engine object.

Related

Shared container accessed by different threads

I have a concurrent_vector (ppl) container declared as a global variable that represents the entry to two functions/threads.
I want it to be accessed by the threads simultaneously (one for reading and one for writing/resizing). My program (in C++) includes a section where I check if the container is empty. Since one thread shows that the buffer is empty while the other desn't, it seems to me that both threads operate on two distinct containers although I defined only one.
#include "stdafx.h"
#include "ppl.h"
concurrent_vector<dataElm> ResultImage;
int AcquireImages(CameraPtr pCam){
continue_recording = true;
pCam->BeginAcquisition();
int imageCnt = 0;
while (continue_recording == true)
{
ImagePtr _p = pCam->GetNextImage(1000);
imageCnt = imageCnt + 1;
dataElm obj = constructelm(_p, &loc, imageCnt - 1);
ResultImage.push_back(obj);
cout << "is buffer empty? " << ResultImage.empty() << endl;
}
//...
}
void Cam(){
//...
pCam->Init();
INodeMap& nodeMap = pCam->GetNodeMap();
result = result | AcquireImages(pCam);
pCam = nullptr;
//...
}
void saveImages() {
//...
cout << "ResultImage.empty() = " << ResultImage.empty() << endl;
if (ResultImage.empty() == false) {
//saving the image
}
else
{
Sleep(20);
}
}
int main(int, char**){
std::thread producer(Cam);
std::thread consumer1(saveImages);
producer.join();
consumer1.join();
return 0;
}
error message
Also, do I need to add synchronization primitives even though I'm using concurrent_vector?
I'm new to multi-threading so I'm sorry if my question seems stupid and excuse my english, i'm not american native.

SDL and C++: Waiting for multiple threads to finish

I am having trouble to fix the following problem:
I have 10 threads that don't need to interact with each other and therefore can all run simultaneusly.
I create them in a loop.
However I need to wait until all threads are done until I can continue with the code that starts after the for loop.
Here is the problem in pseudo code:
//start threads
for (until 10) {
SDL_Thread* thread = SDL_CreateThread();
}
//the rest of the code starts here, all threads need to be done first
What's the best way to get this done?
I need to stay platform independent with that problem, that's why I try to only use SDL-functions.
If there is another platform independent solution for c++, I am fine with that too.
You can take the following approach:
const int THREAD_COUNT = 10;
static int ThreadFunction(void *ptr);
{
// Some useful work done by thread
// Here it will sleep for 5 seconds and then exit
sleep ( 5 );
return 0;
}
int main()
{
vector<SDL_Thread*> threadIdVector;
// create 'n' threads
for ( int count = 0; count < THREAD_COUNT; count++ )
{
SDL_Thread *thread;
stringstream ss;
ss << "Thread::" << count;
string tname = ss.str();
thread = SDL_CreateThread( ThreadFunction, tname, (void *)NULL);
if ( NULL != thread )
{
threadIdVector.push_back ( thread );
}
}
// iterate through the vector and wait for each thread
int tcount = 0;
vector<SDL_Thread*>::iterator iter;
for ( iter = threadIdVector.begin();
iter != threadIdVector.end(); iter++ )
{
int threadReturnValue;
cout << "Main waiting for Thread : " << tcount++ << endl;
SDL_WaitThread( *iter, &threadReturnValue);
}
cout << "All Thread have finished execution. Main will proceed...." << endl;
return 0;
}
I ran this program with standard posix libary commands and it worked fine. Then I replaced the posix library calls with SDL Calls. I do not have the SDL library so you may have to compile the code once.
Hope this helps.
You can implement a Semaphor which increments for every running thread, if the thread is done it decrements the Semaphor and your main programm waits until it is 0.
There are plenty example how semaphore is implemented and by that it will be platform independent.

boost::threads example and heap corruption message

I'm quite new to boost::threads, I read the documentation and but i'm having some trouble applying it in practice, perhaps you can help? First of all, I have taken the time to write a self contained code listing that demonstrates 2 types of behavior that I cannot yet understand...
The program allows the user to issue 3 different commands,
task [name]
info
quit
The purpose is that task will launch some work on a new thread, but then return back to the command prompt while the work is carried out. The user can give the info command to find out which tasks have completed and which have not.
Im using a dual core Win7 machine and Visual Studio 2008 Express.
Problem 1>
Issuing the command, task p1 p2 p3, starts 3 tasks running. This can be checked by issuing info. After a few seconds the work is complete, however for some reason the completed flag is not always set true on 1 or 2 of the tasks.
Problem 2>
Quiting the program then produces the following message:
Windows has triggered a breakpoint in example.exe. This may be due to a corruption of the heap, which indicates a bug in example.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while example.exe has focus.
The output window may have more diagnostic information.
Hopefully you can reproduce this behavior and help.
Thanks in advance.
Alex.
//WARNING: THIS CODE DOES NOT BEHAVE EXACTLY AS INTENDED
#include <iostream>
#include <string>
#include <sstream>
#include <boost/thread.hpp>
using namespace std;
class task {
public:
string mname;
bool completed;
void start()
{
int a = 0;
for (int i=0 ; i<10000; i++)
{
for (int j=0 ; j<100000; j++)
{
a= i*2;
}
}
this->completed = true;
}
task(string name)
{
mname = name;
completed = false;
}
};
class taskManager{
public:
boost::thread_group threads;
void startTask( string name )
{
//add new task to vector list
mtasks.push_back( task(name) );
// execute start() on a new thread
threads.create_thread( boost::bind( &task::start, &mtasks.back()) );
}
int tasksTotal()
{
return mtasks.size();
}
string taskInfo(int i)
{
string compstr("Not Completed");
if ( mtasks[i].completed == true )
{
compstr = "Completed";
}
return mtasks[i].mname + " " + compstr;
}
private:
vector<task> mtasks;
};
int main(int argc, char* argv[])
{
string cmd, temp;
stringstream os;
bool quit = false;
taskManager mm;
cout << "PROMPT>";
while (quit == false)
{
//Wait for a valid command from user
getline(cin,cmd);
// Reset stringstream and assign new cmd string
os.clear();
os << "";
os << cmd;
//parse input string
while (os >> temp)
{
if ( temp.compare("task") == 0 )
{
while (os >> temp) { mm.startTask( temp ); }
}
if ( temp.compare("info") == 0 )
{
// Returns a list of all completed and not completed tasks
for (int i = 0; i<mm.tasksTotal(); i++)
{
cout << mm.taskInfo(i).c_str() << endl;
}
}
if ( temp.compare("quit") == 0 ){ quit = true; }
}
cout << "PROMPT>";
}
mm.threads.join_all();
return 0;
};
There is a problem with your code in the taskManager::startTask method:
mtasks.push_back( task(name) );
// execute start() on a new thread
threads.create_thread( boost::bind( &task::start, &mtasks.back())
The problem here is that on pushing back a new task, your vector might have to reallocate some space and such invalidate the references to your old vector elements, such the following calls to taskinfo will reference to the wrong elements. As you delete the old elements your heap will somehow get corrupted.
An easy fix would be to reserve some space for the vector in the constructor of your taskManager class, however you should probably change the design of your task/taskmanager model instead. Another way would be to use a std::deque, as that one won't reallocate memory.

How do I reverse set_value() and 'deactivate' a promise?

I have a total n00b question here on synchronization. I have a 'writer' thread which assigns a different value 'p' to a promise at each iteration. I need 'reader' threads which wait for shared_futures of this value and then process them, and my question is how do I use future/promise to ensure that the reader threads wait for a new update of 'p' before performing their processing task at each iteration? Many thanks.
You can "reset" a promise by assigning it to a blank promise.
myPromise = promise< int >();
A more complete example:
promise< int > myPromise;
void writer()
{
for( int i = 0; i < 10; ++i )
{
cout << "Setting promise.\n";
myPromise.set_value( i );
myPromise = promise< int >{}; // Reset the promise.
cout << "Waiting to set again...\n";
this_thread::sleep_for( chrono::seconds( 1 ));
}
}
void reader()
{
int result;
do
{
auto myFuture = myPromise.get_future();
cout << "Waiting to receive result...\n";
result = myFuture.get();
cout << "Received " << result << ".\n";
} while( result < 9 );
}
int main()
{
std::thread write( writer );
std::thread read( reader );
write.join();
read.join();
return 0;
}
A problem with this approach, however, is that synchronization between the two threads can cause the writer to call promise::set_value() more than once between the reader's calls to future::get(), or future::get() to be called while the promise is being reset. These problems can be avoided with care (e.g. with proper sleeping between calls), but this takes us into the realm of hacking and guesswork rather than logically correct concurrency.
So although it's possible to reset a promise by assigning it to a fresh promise, doing so tends to raise broader synchronization issues.
A promise/future pair is designed to carry only a single value (or exception.). To do what you're describing, you probably want to adopt a different tool.
If you wish to have multiple threads (your readers) all stop at a common point, you might consider a barrier.
The following code demonstrates how the producer/consumer pattern can be implemented with future and promise.
There are two promise variables, used by a producer and a consumer thread. Each thread resets one of the two promise variables and waits for the other one.
#include <iostream>
#include <future>
#include <thread>
using namespace std;
// produces integers from 0 to 99
void producer(promise<int>& dataready, promise<void>& consumed)
{
for (int i = 0; i < 100; ++i) {
// do some work here ...
consumed = promise<void>{}; // reset
dataready.set_value(i); // make data available
consumed.get_future().wait(); // wait for the data to be consumed
}
dataready.set_value(-1); // no more data
}
// consumes integers
void consumer(promise<int>& dataready, promise<void>& consumed)
{
for (;;) {
int n = dataready.get_future().get(); // wait for data ready
if (n >= 0) {
std::cout << n << ",";
dataready = promise<int>{}; // reset
consumed.set_value(); // mark data as consumed
// do some work here ...
}
else
break;
}
}
int main(int argc, const char*argv[])
{
promise<int> dataready{};
promise<void> consumed{};
thread th1([&] {producer(dataready, consumed); });
thread th2([&] {consumer(dataready, consumed); });
th1.join();
th2.join();
std::cout << "\n";
return 0;
}

Why doesn't my DirectX program recognize that I've released the escape key? (C++)

EDIT: After even more code modification, the error is still there, modified code shown:
KeyDown():
const int input_bit_num = 0x8000;
char keys[256];
bool KeyDown(int key)
{
return (keys[key] & input_bit_num) != 0;
}
PollKeyboard():
LPDIRECTINPUTDEVICE8 di_keyboard;
void PollKeyboard()
{
long result = di_keyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys);
char para[16];
itoa(result, para, 17);
if(result != DI_OK) MessageBox(NULL, para, "ERROR", MB_OK);
}
When I try to put MessageBox within a KeyDown() if statement (as seen below in the game loop), the MessageBox simply coninues to appear even if I stop pressing the key, ie: I press , the "Would you like to quit?" message box appears, I say no, It disappears and then instantly reappears, as if I were still holding the key.
This is my loop:
void GameRun(HWND hWnd) //called once every frame
{
PollKeyboard();
if(GetTickCount - start >= 30)
{
if(KeyDown(DIK_LEFT))
MoveLeft();
if(KeyDown(DIK_RIGHT))
MoveRight();
}
if(d3ddev->BeginScene())
{
//rendering
}
if(KeyDown(DIK_ESCAPE))
{
//any MessageBox()
int result = MessageBox(hWnd, "I'm causing so much trouble!", "IMMORTAL", MB_YESNOCANCEL);
if(result == IDYES)
//end
}
}
EDIT: The catch in PollKeyboard() displays the sequence 53gd6bcc, I could not, however, find the error code it corresponds to.
EDIT: After another test, I saw that even if the MessageBox is not within a KeyDown() if statement, the glitch still occurs.
EDIT: After a bit more testing, it appears that MessageBox itself is causing the glitch.
Because the sample code works, something else in your program is causing the bug. Try moving bits of the code below into your own until it works, then you will know which section of code was culprit.
Sample Code
Alright, huge code block coming up. This code works correctly for me. (Escape, along with all other keys successfully activate and deactivate). It's large, commented, and explains things fairly well. Try this, if it works, we'll examine other parts of your program, if not, I can only leave you with "Good luck", and take what you want:
// DirectInput
#define DIRECTINPUT_VERSION 0x0800
#include<dinput.h>
// Standard stuff
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
// Link from code, MSVC specific, could be done in project settings
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
// Utility lexical_cast, use Boost if possible.
// Simple replacement, converts a stream-able `T`
// to a string
template <typename T>
const std::string lexical_cast(const T& pValue)
{
std::stringstream ss;
ss << pValue;
return ss.str();
}
// Utility function + macro to execute DirectX code with exceptions.
// Kinda ugly, but helpful for us.
void check_error(HRESULT pResult, const std::string& pFuncName)
{
// DI_OK == S_OK, but S_OK is more general, so we'll use that
if (pResult != S_OK)
{
throw std::runtime_error("Error executing: " + pFuncName +
"! Returned: " + lexical_cast(pResult));
}
}
// Macro, makes calling the function easier. It is wrapped in
// an `if` statement for reasons outlined in:
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.5
#define CHECK_ERROR(x) if (true) { check_error(x, #x); } else (void)0
// The above gives the warning:
// "warning C4127: conditional expression is constant", disable below:
#pragma warning(disable: 4127)
// Manages input
class input_manager
{
public:
// Constants
static const int NumberKeys = 256;
// Creation
input_manager(void)
{
// Create input and keyboard (like I said, ugly macro, but helpful :] )
CHECK_ERROR(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, reinterpret_cast<void**>(&_input), 0));
CHECK_ERROR(_input->CreateDevice(GUID_SysKeyboard, &_keyboard, 0));
CHECK_ERROR(_keyboard->SetDataFormat(&c_dfDIKeyboard));
CHECK_ERROR(_keyboard->Acquire());
}
~input_manager(void)
{
// Free resources. Note: Many programmers
// unnecessarily wrap this stuff in
// `if (_keyboard !=0)`, and then
// `_keyboard = 0`. This is completely unnecessary,
// because destructors are only run one time.
// Also, I can assume they are valid, because if they
// weren't, we wouldn't be here (an exception would have
// been thrown)
_keyboard->Unacquire();
_keyboard->Release();
_input->Release();
// Also, if we wrapped this into a nice RAII class, we wouldn't
// be forced to write a destructor, but this is outside the scope.
// Feel free to ask how; additionally, since we're on the topic, if you'd
// like more tips handling input (I've written PLENTY of input managers)
// I'm free for asking about things like testing for triggers rather than pressed
// ("was it pressed, regardless if it's being held now" versus
// "is it being pressed"), etc.
}
// Operations
void update(void)
{
CHECK_ERROR(_keyboard->GetDeviceState(NumberKeys, reinterpret_cast<void*>(&_keys)));
}
// Query
bool key_pressed(int pKey) const
{
return test_key(pKey);
}
// Might wrap into an operator[] for convenience.
private:
// Constants
static const int PressMask = 0x80;
// Sorry for the confusion, but indeed, with
// `char`s the mask is simply 0x80.
// Utility
bool test_key(int pKey) const
{
return (_keys[pKey] & PressMask) != 0;
}
// Members
LPDIRECTINPUT8 _input;
LPDIRECTINPUTDEVICE8 _keyboard;
char _keys[NumberKeys];
};
void test_keys(const input_manager& input)
{
bool anyPressed = false;
for (unsigned i = 0; i < input_manager::NumberKeys; ++i)
{
if (input.key_pressed(i))
{
std::cout << "Pressing: " << i << std::endl;
anyPressed = true;
}
}
if (!anyPressed)
{
std::cout << "No keys pressed." << std::endl;
}
}
void execute(void)
{
input_manager input;
std::cout << "Press Q to quit." << std::endl;
bool running = true;
while (running)
{
input.update();
if (input.key_pressed(DIK_Q))
{
running = false;
}
test_keys(input);
Sleep(0); // give some processor time
}
}
int main(void)
{
// Place real code in an execute function, so main
// is clean and ready to catch exceptions:
try
{
execute();
}
catch (const std::exception& e)
{
// Error!
std::cerr << "Unhandled exception:" << e.what() << std::endl;
}
}
Old suggestion:
Try catching the return value from GetDeviceState:
HRESULT result = // v Prefer C++-style casts
di_keyboard->GetDeviceState(sizeof(keys), reinterpret_cast<void*>(&keys);
if (result != DI_OK)
{
// uh-oh
std::cout << result << std::endl;
}
Compare it against the table here.
Old Semi-Answer:
Shortly after editing in the code in the Extra Stuff section, I realized the error, sorry I didn't catch it earlier. You're testing the wrong bit :)
Observe:
// v HERE! Should be 0x8000, not 0x80.
return (GetAsyncKeyState(pKeyCode) & 0x8000) != 0;
Try that:
int KeyDown(int key)
{
return (keys[key] & 0x8000);
}
Also, this should be moved into a constant to avoid magic numbers:
// somewhere, probably in the private section of the class or in a detail namespace:
static const int PushedMask = 0x8000;
// code reads better:
int KeyDown(int key)
{
return (keys[key] & PushedMask);
}
Lastly, in C++ you have a bool type, so take advantage of it!
// v here
bool KeyDown(int key)
{
return (keys[key] & PushedMask);
}
I know Visual Studio will warn about this conversion from int to bool, so you can get rid of it while also making your intents clearer:
bool KeyDown(int key)
{
return (keys[key] & PushedMask) != 0; // or == 1, your choice
}
Extra Stuff:
Try the following code:
#include <iostream>
#include <windows.h>
bool key_pressed(int pKeyCode)
{
return (GetAsyncKeyState(pKeyCode) & 0x8000) != 0;
}
void test_keys(void)
{
for (unsigned i = 0; i < 255; ++i)
{
if (key_pressed(i))
{
std::cout << "Pressing: " << i << std::endl;
}
}
}
int main(void)
{
bool running = true;
while (running)
{
if (key_pressed(VK_ESCAPE))
{
running = false;
}
test_keys();
Sleep(0);
}
}
This works for me (responds to all keys, quits on escape). Minimal test case for GetAsyncKeyState. If this does not work, please add OS, Keyboard, etc, in your comment.
If you create a MessageBox(Null,...) you won't have any control over the window after it's creation. IE, the window won't disappear when you depress the key.
As for why it keeps on appearing, seems to have something to do with this:
const int input_bit_num = 0x8000;
char keys[256];
bool KeyDown(int key)
{
return (keys[key] & input_bit_num) != 0;
}
keys consits of 1 byte long characters, while input_bit_num is a 2 byte value. While I don't honestly know which bit it is that you're looking for (0xff - 0x00 is the domain of 1 byte).
Honestly, I'm surprised that your code runs, unless the & operation is carrying over into keys[key-1] in which case any KeyDown is undefined, and KeyDown(...) when key is 0 is particularly dangerous.