Urban legends aside, I've got too much going on project wise to try and implement any sort of multi-platform.
So here's the bmax/C++ source used, public domain so hopefully someone else can finish it off for us.(this won't be a commercial product from me. ever.)
anyway, enough rambling, here's the juice. (This is the latest version btw, I'd nab it if you're using the above.
You can now pass a pointer to a thread. (Edit-fixed a bug.)
'TheadLayer.c
Freel free to upload any improvements to this thread..or your own.
So here's the bmax/C++ source used, public domain so hopefully someone else can finish it off for us.(this won't be a commercial product from me. ever.)
anyway, enough rambling, here's the juice. (This is the latest version btw, I'd nab it if you're using the above.
You can now pass a pointer to a thread. (Edit-fixed a bug.)
Strict Module PUB.Thread ModuleInfo "Version: 1.00" ModuleInfo "Author:Antony Wells" ModuleInfo "License:Public Domain" ModuleInfo "Copyright: Public Domain" ModuleInfo "Modserver: BRL" '(if they want). I doubt it!. 'Note only win32 link is working(Source code below) so this'll crash out on mac/linux atm..if that. ?win32 Import "ThreadLayer.c" ?macOS 'Import "MacThread.c" ?linux 'Import "LinuxThread.c" ? Import BRL.LinkedList Import BRL.Stream Import BRL.Bank Type TResource Method New() Mutex = makeMutex() End Method Method Delete() cleanMutex( mutex ) closeObject( mutex ) End Method Method Lock() waitForObject( mutex,0) Return 1 End Method Method Unlock() cleanMutex( mutex ) End Method Method GetInt:Int() Return dInt[0] End Method Method getFloat:Float() Return dFloat[0] End Method Method getDouble:Double() Return dDouble[0] End Method Method getStream:TStream() Return dStream End Method Method getBank:TBank() Return dBank End Method Method getType:Object() Return dObject End Method Field dInt:Int Ptr Field dFloat:Float Ptr Field dDouble:Double Ptr Field dBank:TBank Field dObject:Object Field dStream:TStream Field Mutex:Int End Type Type TThread Function Init() Threads = CreateList() SharedData = CreateList() End Function Method New() FlagLock = CreateLock() End Method Method Delete() If handle<>0 cleanThread(handle) closeObject(Handle) handle = 0 End If End Method Function ProtectInt:TResource( Resource:Int Var ) Local TRes:TResource = New TResource TRes.dInt =Varptr Resource Return TRes End Function Function ProtectFloat:TResource( Resource:Float Var) Local TRes:TResource = New TResource TRes.dFloat = Varptr Resource Return TRes End Function Function ProtectBank:TResource( Resource:TBank ) Local TRes:TResource = New TResource TRes.dBank = Resource Return TRes End Function Function ProtectType:TResource( Resource:Object ) Local TRes:TResource = New TResource TRes.dObject = Resource Return TRes End Function Function ProtectStream:TResource( Resource:TStream ) Local TRes:TResource = New TResource TRes.dStream = Resource Return TRes End Function Function Create:TThread( bb_func:Int(tp:Byte Ptr),value:Int=0 ) Local Spawn:TThread = New TThread 'Spawn.Handle = makeThread( bb_func ) Spawn.bbfunc = bb_func ListAddLast Threads,Spawn Spawn.PassValue = New Int[1] Spawn.passValue[0] = Value Return Spawn End Function Method SetParInt(value:Int) PassValue[0]=Value PassMode = 0 End Method Function RunAll() For Local Thread:TThread = EachIn Threads Thread.Pause() Next End Function Function PauseAll() For Local Thread:TThread = EachIn Threads If Thread.Handle<>0 Thread.Pause() EndIf Next End Function Method Active:Byte() ' RequestLock( flagLock ) Return ActiveFlag ' ReleaseLock( flagLock ) End Method Function ResumeAll() For Local Thread:TThread = EachIn Threads If Thread.Handle<>0 Thread.Resume() End If Next End Function Method Run() Handled = makeThreadValue( bbFunc,PassValue) End Method Method Pause() haltThread( Handle ) End Method Method Resume() restartThread( Handle ) End Method Method Stop() cleanThread( Handle ) closeObject( Handle ) Handle = Null End Method Method SetPriority( nPriority:Int ) Assert handle,"Thread not running" AlterThreadPriority( handle,nPriority) End Method 'Waits for a thread to finish, maxwait defines how long to wait for. 0 = as long as it takes. Method Wait(MaxWait:Int=0) waitForObject( Handle,MaxWait ) End Method Field Handle:Int Field ActiveFlag:Byte Global Threads:TList Global Master:TThread Global SharedData:TList Field bbfunc:Int(tp:Byte Ptr) Field passValue:Int Ptr,PassMode:Short Field CapsuleThread:Int,flagLock:Int End Type TThread.Init() Public ?win32 Extern Function makeThread:Int(bb_func:Int(tp:Byte Ptr)) Function waitForObject( threadHandle:Int,MaxWait:Int ) Function makeMutex:Int() Function cleanMutex(mutex:Int) Function closeObject(handle:Int) Function cleanThread(handle:Int) Function AlterThreadPriority( handle:Int,priority:Int) Function haltThread(handle:Int) Function restartThread(handle:Int) Function makeThreadValue:Int(bb_func:Int(tp:Byte Ptr),value:Int Ptr) End Extern ?mac Throw "DreamSpace - BlitzThreads is not yet supported on Mac. Sorry." ?linux Throw "DreamSpace - BlitzThreads is not yet Supported on Linux. Sorry." ? Function CreateThread:TThread( bb_func:Int(tp:Byte Ptr)) Return TThread.Create( bb_func ) End Function Function WaitThread( In:TThread,WaitUntil:Int=0 ) In.Wait( WaitUntil ) End Function 'Returns immediately Function RunThread( In:TThread ) In.Run() End Function Function PauseThread( In:TThread ) In.Pause() End Function Function ResumeThread( In:TThread ) In.Resume() End Function Function StopThread( In:TThread ) In.Stop() End Function Global ActiveThread:TThread Global ActiveFunction:Int(BB_Func:Byte Ptr) Global ActiveMutex = CreateLock() Function CreateLock:Int() Return makeMutex() End Function Function RequestLock:Int(LockID:Int) Return waitForObject( LockId,0 ) End Function Function ReleaseLock(LockId:Int) cleanMutex( lockId ) End Function
'TheadLayer.c
#include <windows.h> // Thread spawner for HANDLE makeThreadValue( int (*function),LPVOID *value){ HANDLE threadHandle; threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)function,value, 0, NULL); return threadHandle; }; HANDLE makeThread(int (*function)){ HANDLE threadHandle; threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)function,NULL, 0, NULL); return threadHandle; }; void AlterThreadPriority( HANDLE threadHandle,int priority){ switch(priority){ case 1: priority = THREAD_PRIORITY_IDLE; break; case 2: priority = THREAD_PRIORITY_LOWEST; break; case 3: priority = THREAD_PRIORITY_BELOW_NORMAL; break; case 4: priority = THREAD_PRIORITY_NORMAL; break; case 5: priority = THREAD_PRIORITY_ABOVE_NORMAL; case 6: priority = THREAD_PRIORITY_HIGHEST; break; case 7: priority = THREAD_PRIORITY_TIME_CRITICAL; break; } SetThreadPriority( threadHandle,priority); } void haltThread( HANDLE threadHandle ){ SuspendThread( threadHandle ); } void restartThread(HANDLE threadHandle){ ResumeThread( threadHandle); } void waitForObject(HANDLE threadHandle,int wait){ if(wait>0){ WaitForSingleObject( threadHandle,wait); }else{ WaitForSingleObject( threadHandle,INFINITE); } } void closeObject( HANDLE in){ CloseHandle( in ); }; void cleanThread( HANDLE threadHandle ){ TerminateThread( threadHandle ,0 ); } void threadActive( HANDLE threadHandle ){ } HANDLE makeMutex(){ return CreateMutex(NULL, 0, NULL); } void cleanMutex( mutexHandle){ ReleaseMutex( mutexHandle ); }
Freel free to upload any improvements to this thread..or your own.