123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- Namespace mojox
- #if __TARGET__<>"emscripten"
- #rem monkeydoc The Console class.
- #end
- Class Console Extends TextView
- #rem monkeydoc Invoked when the console finishes executing a process.
- #end
- Field Finished:Void( exitCode:Int )
-
- #rem monkeydoc Creates a new console.
- #end
- Method New()
- Style=GetStyle( "Console" )
-
- ReadOnly=True
- End
-
- #rem monkeydoc True if the process is running.
- #end
- Property Running:Bool()
- Return _running
- End
-
- #rem monkeydoc The process.
- #end
- Property Process:Process()
- Return _process
- End
-
- #rem monkeydoc Process exit code.
-
- If the process is still running, -1 is returned.
-
- #end
- Property ExitCode:Int()
- If _process And Not _procOpen return _process.ExitCode
- Return -1
- End
-
- #rem monkeydoc Runs a process.
-
- Returns true if the process was successfully started, else false.
-
- Process stdout is written to the console while the process is running.
-
- This method waits for the process to complete, so should always be called on a fiber.
-
- #end
- Method Run:Bool( cmd:String )
-
- If Not Start( cmd )
- Alert( "Failed to start process '"+cmd+"'" )
- Return False
- Endif
-
- Repeat
-
- Local stdout:=ReadStdout()
- If Not stdout Exit
-
- Write( stdout )
- Forever
-
- Return True
- End
- #rem monkeydoc Starts a process.
-
- Returns true if the process was successfully started, else false.
-
- #end
- Method Start:Bool( cmd:String )
-
- If _running Return False
-
- Local process:=New Process
-
- process.Finished=Lambda()
- _procOpen=False
- UpdateRunning()
- End
-
- process.StdoutReady=Lambda()
-
- Local stdout:=process.ReadStdout()
-
- ' Print "**** CONSOLE STDOUT *****"
- ' Print stdout
- ' Print "***** END STDOUT *****"
-
- If Not stdout
- If _stdout _stdoutBuf.Add( _stdout )
- _stdoutOpen=False
- UpdateRunning()
- Return
- Endif
-
- stdout=_stdout+(stdout.Replace( "~r~n","~n" ).Replace( "~r","~n" ))
-
- Local i0:=0
- Repeat
- Local i:=stdout.Find( "~n",i0 )
- If i=-1
- _stdout=stdout.Slice( i0 )
- Exit
- Endif
- _stdoutBuf.Add( stdout.Slice( i0,i+1 ) )
- i0=i+1
- Forever
-
- If _stdoutWaiting And Not _stdoutBuf.Empty _stdoutWaiting.Set( True )
-
- End
-
- If Not process.Start( cmd ) Return False
-
- _process=process
-
- _running=True
- _procOpen=True
- _stdoutOpen=True
- _stdout=""
- _stdoutBuf.Clear()
- _stdoutWaiting=Null
-
- Return True
- End
-
- #rem monkeydoc Reads process stdout.
-
- If an empty string is returned, the process has finished.
-
- This method may have to wait for stdout to become available, so should always be called on a fiber.
-
- #end
- Method ReadStdout:String()
-
- While _stdoutBuf.Empty
-
- If Not _stdoutOpen
- If _procOpen
- _stdoutWaiting=New Future<Bool>
- _stdoutWaiting.Get()
- _stdoutWaiting=Null
- Endif
- Return ""
- Endif
-
- _stdoutWaiting=New Future<Bool>
- _stdoutWaiting.Get()
- _stdoutWaiting=Null
- Wend
-
- Return _stdoutBuf.RemoveFirst()
- End
-
- #rem monkeydoc Writes to process stdin.
- #end
- Method WriteStdin( str:String )
-
- If Not _procOpen Return
-
- _process.WriteStdin( str )
- End
-
- #rem monkeydoc Terminates the process.
- #end
- Method Terminate()
- If Not _procOpen Return
-
- _process.Terminate()
- End
-
- #rem monkeydoc Writes text to the console.
- #end
- Method Write( text:String )
-
- AppendText( text )
- End
-
- Private
-
- Field _process:Process
-
- Field _running:Bool
- Field _procOpen:Bool
- Field _stdoutOpen:Bool
- Field _stdout:String
- Field _stdoutBuf:=New StringList
- Field _stdoutWaiting:Future<Bool>
-
- Method UpdateRunning()
-
- If Not _running Or _procOpen Or _stdoutOpen Return
-
- _running=False
-
- Finished( _process.ExitCode )
-
- If _stdoutWaiting _stdoutWaiting.Set( True )
- End
- End
- #endif
|