D:\ALASKA\XPPW32\SOURCE\samples\basics\THREAD\Coffee.prg
also es geht um die Verwendung von Multi Threads & Signal.
Ich hab statt XbpDialog als Demo XbpCrt gemacht und nun Probleme
das in meine Hybrid Application einzubaun. Die Thread scheinen alle
soweit zu laufen und die SetAppWindow()/SetAppFocus() stimmt "im
Prinzip" d.h. "alte Fenster" bleiben erhalten wenn die den "Focus" verlieren
Nun kann es aber sein das ich eine "lange Ausgabe" habe und die noch
nicht "stable" ist wenn ich in ein "anderes Fenster" springen will ...
also denke ich mir muss ich wohl Signal() verwenden um den einzeln
Thread() mitzuteilen ob er "darf" oder nicht.
Die "Grundidee" ist nun die "Kaffeemachine" welche nur eine "capacity"
von exakt 1 Tasse "Kaffee" hat. Nur der "Programmer" der zur der
"Kaffeemachine" geht ( :Enter ) kann sich 1 Tasse "Coffee" holen
( :takecoffee ) und dann arbeiten.
also "entziehe" ich allen "Programmern" der "Coffee" und gebe nur dem
"Fenster" was aktive ist 1 Tasse "Coffee" womit dann die "Kaffeemachine"
leer sein sollte.
das dumme scheint nun bei "langen Ausgaben" zu sein, den trotz "Coffee"
= 0 arbeitet der "Programmer" weiter an der "langen Ausgabe" um erst
dann zu reagieren ... ?!
ich müsste also irgendwie noch raus bekommen ob der "Programmer"
noch an einer "langen Ausgabe" ist ober ob er das :wait() kapiert hat.
also wie bekomme das raus und wie kann ich "lange Ausgaben"
entsprechend anpassen ?
Code: Alles auswählen
ohne weiter Sinn
PROCEDURE FILLSCR
LOCAL x,y
CLS
FOR x = 1 TO MAXROW()
FOR y = 1 TO MAXCOL()
@ x,y say "*"
INKEY(0.001)
NEXT
NEXT
RETURN
Jimmy
Code: Alles auswählen
procedure appsys()
return
PROCEDURE Main
LOCAL i, oMachine
LOCAL aTime := { 130, 100, 140, 90, 100, 110, 150, 120, 100 , 1000}
LOCAL aNames:= { "Martin ", "Hubert ", ; // nach Forum "Beitr„ge"
"Manfred ", "Tom ", ;
"Jan ", "Andreas ", ;
"Olaf ", "Wolfgang", ;
"Marcus ", "Jimmy " }
LOCAL aPosi := { {000,000+50}, {330,000+50}, ;
{000,075+50}, {330,075+50}, ;
{000,150+50}, {330,150+50}, ;
{000,225+50}, {330,225+50}, ;
{000,300+50}, {330,300+50} }
local opar:=xbpDialog():new(setappwindow(),,{0,0},{800,600},,.t.)
opar:create()
oMachine := KaffeeMachine():new( 20 , opar:drawingarea )
oMachine:start()
FOR i := 1 TO 10
Programmer():new( aNames[i], aTime[i], oMachine, opar:drawingarea, aPosi[i] ):start()
NEXT
SETAPPFOCUS(opar)
Inkey(0)
RETURN
CLASS KaffeeMachine FROM Thread
EXPORTED:
VAR capacity, Kaffee, waterIsFilled, KaffeeIsReady, ocrt1
METHOD init, execute
SYNC METHOD enter
ENDCLASS
METHOD KaffeeMachine:init( nCapacity, opar)
::thread:init()
::setInterval( 10 )
::Kaffee := 0
::capacity := nCapacity
::waterIsFilled := Signal():new()
::KaffeeIsReady := Signal():new()
::ocrt1 := xbpcrt():new(opar,,{ 0, 500}, 4,80):create()
RETURN self
METHOD KaffeeMachine:enter( oProgrammer )
oProgrammer:takeCoffee()
RETURN self
METHOD KaffeeMachine:execute
LOCAL n
IF ::Kaffee < 1
SETAPPFOCUS(::ocrt1)
SETAPPWINDOW(::ocrt1)
DispoutAt( 1, 0, PadR( "Kaffee ist alle! ",80 ), "W+/B" )
::waterIsFilled:wait()
n := 0
DO WHILE ++n <= ::capacity
SETAPPWINDOW(::ocrt1)
DispoutAt( 1, 0, PadR( "Kaffeemaschine l„uft! "+Replicate(Chr(219),2*n), 80 ), "W+/B" )
Sleep(35)
ENDDO
::Kaffee := ::capacity
ENDIF
SETAPPWINDOW(::ocrt1)
DispoutAt( 1, 0, PadR( "Kaffee ist fertig! "+Replicate(Chr(176),::Kaffee*2), 80 ) )
DispoutAt( 2, 0, PadR( "", 80 ), "W+/N" )
::KaffeeIsReady:signal()
RETURN self
CLASS Programmer FROM Thread
EXPORTED:
VAR name, coffee, coffeeMachine, ocrt2
METHOD init, execute, takeCoffee
ENDCLASS
METHOD Programmer:init( cName, nInterval, oMachine, opar, aposi)
::thread:init()
::setInterval( nInterval )
::coffee := 0
::name := cName
::coffeeMachine := oMachine
::ocrt2 := xbpcrt():new(opar,,aposi,3,40,cName):create()
RETURN self
METHOD Programmer:execute
LOCAL nRow := 1
IF ::coffee == 0
SETAPPFOCUS(::ocrt2)
SETAPPWINDOW(::ocrt2)
DispoutAt( nRow, 0, PadR( ::name + " BRAUCHT Kaffee", 80), "W+/R" )
::coffeeMachine:enter( self )
ENDIF
SETAPPWINDOW(::ocrt2)
DispoutAt( nRow, 0, PadR( ::name + IF(UPPER(::name)="JIMMY",;
" testet - ",;
" arbeitet - ");
+Replicate( ".", 10*::coffee), 80) )
::coffee := Max( ::coffee - 0.1, 0 )
RETURN
METHOD Programmer:takeCoffee
LOCAL nRow := 1
IF ::coffeeMachine:Kaffee < 1
SETAPPFOCUS(::CoffeeMachine:ocrt1)
SETAPPWINDOW(::CoffeeMachine:ocrt1)
DispoutAt( nRow+1, 0, PadR( ::name + " KOCHT Kaffee", 80 ), "W+/B" )
::coffeeMachine:waterIsFilled:signal()
ENDIF
::coffeeMachine:KaffeeIsReady:wait()
SETAPPFOCUS(::ocrt2)
SETAPPWINDOW(::ocrt2)
DispoutAt( nRow, 0, PadR( ::name + " nimmt sich Kaffee ", 80 ), "N/G" )
::coffeeMachine:Kaffee -= 1
::coffee := 1
Sleep(100)
RETURN self
*
* eof
*