From the original Thread. Just checked the rar and there were no docs/source, just the mod `mam.
It's object driven, although there are function wrappers for those used to that.
Classes are(There's no docs)
TThread.
Global functions(Contained within TThread. I.e TThread.
Create() )
Create( BlitzFunction ) Create a thread and return a TThread object.
RunAll() 'Runs all threads
PauseAll() 'Pauses all threads
StopAll() 'Stops all threads
Local functions specific to each thread instance,
Run() 'Runs the function provided when creating the thread, in another thread.
Priority( Value:Int) 'Set the threads priority, value ranges from 1 to 7. (default = 3, pre-set)
Pause() 'Pause the thread
Resume() 'Resume the thread,
-
Global functions within TThread to allow async data access,
All return a TResource object/integer handle.
ProtectInt( x variable )
ProtectFloat( x variable )
ProtectBank( Bank:TBank )
ProtectStream( Stream:TStream )
-
With the tResource object returned, you can lock access rights to it within your thread,
Wrapper functions are,
ThreadHandle =CreateThread( Function )
PauseThread( ThreadHandle )
ThreadPriority( ThreadHandle,Priority )
PauseThread(Threadhandle)
ResumeThread(ThreadHandle)
StopThread(ThreadHandle)
RunThread(ThreadHandle)
There's also a manual locking system, in addition to protected storage.
Lock = CreateLock()
RequestLock(Lock)
ReleaseLock(lock)
which allows you to restrict threads of the same locking patterns to one run at a time.(Prevent deadlocks..if you're lucky :) )
TestApp
Simple mode
Update = CreateThread( UpdateVal )
NetWork = CreateThread( PrintVal )
RunThread(Update)
RunThread(NetWork)
Global ourVal
Function updateVal:Int(bb_func:Byte Ptr)
repeat
ourVal:+1
forever
End function
Function printVal:Int (bb_func:Byte Ptr)
repeat
Print "Val:"+OurVal
Delay 1000
forever
End Function
Print "Thread Handle>"+Res
repeat
Delay 5000
Print "Master thread!"
Forever
Advanced Mode
Update:TThread = TThread.Create( UpdateVal )
NetWork:TThread = TThread.Create( PrintVal )
Update.Run()
Network.Run()
Global ourVal
Function updateVal:Int(bb_func:Byte Ptr)
repeat
ourVal:+1
forever
End function
Function printVal:Int (bb_func:Byte Ptr)
repeat
Print "Val:"+OurVal
Delay 1000
forever
End Function
Print "Thread Handle>"+Res
repeat
Delay 5000
Print "Master thread!"
Forever
Install
To install, copy dreamspace.mod folder into your bmax mod folder(Windows only atm) and you're done.
Source BMX
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 - <span style="background-color: #ffff66; color: #000000; font-weight: bold;">BlitzThreads</span> is not yet supported on Mac. Sorry."
?linux
Throw "DreamSpace - <span style="background-color: #ffff66; color: #000000; font-weight: bold;">BlitzThreads</span> 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
C++ (imported by the bmx code, you don't need VC or anything.]
Call it ThreadLayer.C (Well you don't have it. You do if you want it to work but you don't have to.)
#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 );
}