   Concurrent example not working under linux
  First off, I'm new AngleScript and love'n it! When I got around to trying the "concurrent" example, I saw no output for script "a" or "b". After poking around I found the problem to be with the included linux version of kbhit(). It was getting stuck in there. So after a quick google session I found an alternative version that works good - with GCC anyway. Here's the working version that I found ...Sorry if this is a repost#include <stdio.h>#include <termios.h>#include <unistd.h>#include <fcntl.h>int kbhit( void ) {   struct termios oldt, newt;   int ch;   int oldf;   tcgetattr(STDIN_FILENO, &oldt);   newt = oldt;   newt.c_lflag &= ~(ICANON | ECHO);   tcsetattr(STDIN_FILENO, TCSANOW, &newt);   oldf = fcntl(STDIN_FILENO, F_GETFL, 0);   fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);   ch = getchar();   tcsetattr(STDIN_FILENO, TCSANOW, &oldt);   fcntl(STDIN_FILENO, F_SETFL, oldf);   if(ch != EOF) { ungetc(ch, stdin); return 1;   }   return 0;}   
  I ported the examples to Linux originally and I remember all of them functioning properly. When I get a chance I'll see if I get the same issue.;  Yeah, the kbhit I had wasn't working correctly, the version you posted works like it should.Here is the updated source with the above code from GDTheLaw:#include <iostream>  // cout#include <assert.h>  // assert()#include <vector>#include <angelscript.h>#include "../../../add_on/scriptstring/scriptstring.h"#ifdef _LINUX_ #include <sys/time.h>#include <stdio.h>#include <termios.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#elif defined(__APPLE__)#include <curses.h>#else#include <conio.h>   // kbhit(), getch()#include <windows.h> // timeGetTime()#endifusing namespace std;#ifdef _LINUX_#define UINT unsigned int typedef unsigned int DWORD;// Linux doesn't have timeGetTime(), this essintially does the same// thing, except this is milliseconds since Epoch (Jan 1st 1970) instead// of system start. It will work the same though...DWORD timeGetTime(){timeval time;gettimeofday(&time, NULL);return time.tv_sec*1000 + time.tv_usec/1000;}// kbhit() for linuxint kbhit() {struct termios oldt, newt;int ch;int oldf;tcgetattr(STDIN_FILENO, &oldt);newt = oldt;newt.c_lflag &= ~(ICANON | ECHO);tcsetattr(STDIN_FILENO, TCSANOW, &newt);oldf = fcntl(STDIN_FILENO, F_GETFL, 0);fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);ch = getchar();tcsetattr(STDIN_FILENO, TCSANOW, &oldt);fcntl(STDIN_FILENO, F_SETFL, oldf);if(ch != EOF) {ungetc(ch, stdin);return 1;}return 0;}#elif defined(__APPLE__)#define UINT unsigned inttypedef unsigned int DWORD;// Linux doesn't have timeGetTime(), this essintially does the same// thing, except this is milliseconds since Epoch (Jan 1st 1970) instead// of system start. It will work the same though...DWORD timeGetTime(){timeval time;gettimeofday(&time, NULL);return time.tv_sec*1000 + time.tv_usec/1000;}int kbhit(){if( getch() == ERR )return 0;return 1;}#endif// Function prototypesvoid ConfigureEngine(asIScriptEngine *engine);int  CompileScript(asIScriptEngine *engine);void PrintString(string &str);void PrintNumber(int num);void ScriptSleep(UINT milliSeconds);struct SContextInfo{UINT sleepUntil;asIScriptContext *ctx;};// This simple manager will let us manage the contexts, // in a simple scheme for apparent multithreadingclass CContextManager{public:void AddContext(int funcID);void ExecuteScripts();void SetSleeping(asIScriptContext *ctx, UINT milliSeconds);void AbortAll();vector<SContextInfo> contexts;} contextManager;void MessageCallback(const asSMessageInfo *msg, void *param){const char *type = "ERR ";if( msg->type == asMSGTYPE_WARNING ) type = "WARN";else if( msg->type == asMSGTYPE_INFORMATION ) type = "INFO";printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);}asIScriptEngine *engine = 0;int main(int argc, char **argv){int r;// Create the script engineengine = asCreateScriptEngine(ANGELSCRIPT_VERSION);if( engine == 0 ){cout << "Failed to create script engine." << endl;return -1;}// The script compiler will send any compiler messages to the callback functionengine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);// Configure the script engine with all the functions, // and variables that the script should be able to use.ConfigureEngine(engine);// Compile the script coder = CompileScript(engine);if( r < 0 ) return -1;contextManager.AddContext(engine->GetModule("script1")->GetFunctionIdByDecl("void main()"));contextManager.AddContext(engine->GetModule("script2")->GetFunctionIdByDecl("void main()"));// Print some useful information and start the input loopcout << "This sample shows how two scripts can be executed concurrently." << endl; cout << "Both scripts voluntarily give up the control by calling Sleep()." << endl;cout << "Press any key to terminate the application." << endl;for(;;){// Check if any key was pressedif( kbhit() ){contextManager.AbortAll();break;}// Allow the contextManager to determine which script to execute nextcontextManager.ExecuteScripts();}// Release the engineengine->Release();return 0;}void ConfigureEngine(asIScriptEngine *engine){int r;// Register the script string type// Look at the implementation for this function for more information  // on how to register a custom string type, and other object types.// The implementation is in "/add_on/scriptstring/scriptstring.cpp"RegisterScriptString(engine);// Register the functions that the scripts will be allowed to user = engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString), asCALL_CDECL); assert( r >= 0 );r = engine->RegisterGlobalFunction("void Print(int)", asFUNCTION(PrintNumber), asCALL_CDECL); assert( r >= 0 );r = engine->RegisterGlobalFunction("void Sleep(uint)", asFUNCTION(ScriptSleep), asCALL_CDECL); assert( r >= 0 );}int CompileScript(asIScriptEngine *engine){int r;// This script prints a message 3 times per secondconst char *script1 = "int count = 0; ""void main()    ""{    "    "  for(;;) ""  {  ""    Print(\"A :\"); ""    Print(count++); ""    Print(\"\\n\"); ""    Sleep(333);""  }  ""}    ";// This script prints a message once per secondconst char *script2 ="int count = 0; ""void main()    ""{    ""  for(;;) ""  {  ""    Print(\" B:\"); ""    Print(count++); ""    Print(\"\\n\"); ""    Sleep(1000);    ""  }  ""}    ";// Build the two script into separate modules. This will make them have// separate namespaces, which allows them to use the same name for functions// and global variables.asIScriptModule *mod = engine->GetModule("script1", asGM_ALWAYS_CREATE);r = mod->AddScriptSection("script1", script1, strlen(script1));if( r < 0 ) {cout << "AddScriptSection() failed" << endl;return -1;}r = mod->Build();if( r < 0 ){cout << "Build() failed" << endl;return -1;}mod = engine->GetModule("script2", asGM_ALWAYS_CREATE);r = mod->AddScriptSection("script2", script2, strlen(script2));if( r < 0 ){cout << "AddScriptSection() failed" << endl;return -1;}r = mod->Build();if( r < 0 ){cout << "Build() failed" << endl;return -1;}return 0;}void PrintString(string &str){cout << str;}void PrintNumber(int num){cout << num;}void ScriptSleep(UINT milliSeconds){// Get a pointer to the context that is currently being executedasIScriptContext *ctx = asGetActiveContext();if( ctx ){// Suspend it's execution. The VM will continue until the current // statement is finished and then return from the Execute() methodctx->Suspend();// Tell the context manager when the context is to continue executioncontextManager.SetSleeping(ctx, milliSeconds);}}void CContextManager::ExecuteScripts(){// Check if the system time is higher than the time set for the contextsUINT time = timeGetTime();for( int n = 0; n < (signed)contexts.size(); n++ ){if( contexts[n].ctx && contexts[n].sleepUntil < time ){int r = contexts[n].ctx->Execute();if( r != asEXECUTION_SUSPENDED ){// The context has terminated execution (for one reason or other)contexts[n].ctx->Release();contexts[n].ctx = 0;}}}}void CContextManager::AbortAll(){// Abort all contexts and release them. The script engine will make // sure that all resources held by the scripts are properly released.for( int n = 0; n < (signed)contexts.size(); n++ ){if( contexts[n].ctx ){contexts[n].ctx->Abort();contexts[n].ctx->Release();contexts[n].ctx = 0;}}}void CContextManager::AddContext(int funcID){// Create the new contextasIScriptContext *ctx = engine->CreateContext();if( ctx == 0 ){cout << "Failed to create context" << endl;return;}// Prepare it to execute the functionint r = ctx->Prepare(funcID);if( r < 0 ){cout << "Failed to prepare the context" << endl;return;}// Add the context to the list for executionSContextInfo info = {0, ctx};contexts.push_back(info);}void CContextManager::SetSleeping(asIScriptContext *ctx, UINT milliSeconds){// Find the context and update the timeStamp  // for when the context is to be continuedfor( int n = 0; n < (signed)contexts.size(); n++ ){if( contexts[n].ctx == ctx ){contexts[n].sleepUntil = timeGetTime() + milliSeconds;}}};  Thanks for the fix. I've checked it into the SVN.   ;  The same faulty kbhit() is also in other examples like coroutines and events. Just wanted to make sure you got them too. Thanks and keep up the good work!   ;  Ah, yes. I forgot to check that. I'll have those fixed also.   ;  I've fixed the kbhit function in all three samples that used it. Let me know if there are any other problems.Thanks,Andreas   