2
0

console.monkey2 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. Namespace mojox
  2. #if __TARGET__<>"emscripten"
  3. #rem monkeydoc The Console class.
  4. #end
  5. Class Console Extends TextView
  6. #rem monkeydoc Invoked when the console finishes executing a process.
  7. #end
  8. Field Finished:Void( exitCode:Int )
  9. #rem monkeydoc Creates a new console.
  10. #end
  11. Method New()
  12. Style=GetStyle( "Console" )
  13. ReadOnly=True
  14. End
  15. #rem monkeydoc True if the process is running.
  16. #end
  17. Property Running:Bool()
  18. Return _running
  19. End
  20. #rem monkeydoc The process.
  21. #end
  22. Property Process:Process()
  23. Return _process
  24. End
  25. #rem monkeydoc Process exit code.
  26. If the process is still running, -1 is returned.
  27. #end
  28. Property ExitCode:Int()
  29. If _process And Not _procOpen return _process.ExitCode
  30. Return -1
  31. End
  32. #rem monkeydoc Runs a process.
  33. Returns true if the process was successfully started, else false.
  34. Process stdout is written to the console while the process is running.
  35. This method waits for the process to complete, so should always be called on a fiber.
  36. #end
  37. Method Run:Bool( cmd:String )
  38. If Not Start( cmd )
  39. Alert( "Failed to start process '"+cmd+"'" )
  40. Return False
  41. Endif
  42. Repeat
  43. Local stdout:=ReadStdout()
  44. If Not stdout Exit
  45. Write( stdout )
  46. Forever
  47. Return True
  48. End
  49. #rem monkeydoc Starts a process.
  50. Returns true if the process was successfully started, else false.
  51. #end
  52. Method Start:Bool( cmd:String )
  53. If _running Return False
  54. Local process:=New Process
  55. process.Finished=Lambda()
  56. _procOpen=False
  57. UpdateRunning()
  58. End
  59. process.StdoutReady=Lambda()
  60. Local stdout:=process.ReadStdout()
  61. ' Print "**** CONSOLE STDOUT *****"
  62. ' Print stdout
  63. ' Print "***** END STDOUT *****"
  64. If Not stdout
  65. If _stdout _stdoutBuf.Add( _stdout )
  66. _stdoutOpen=False
  67. UpdateRunning()
  68. Return
  69. Endif
  70. stdout=_stdout+(stdout.Replace( "~r~n","~n" ).Replace( "~r","~n" ))
  71. Local i0:=0
  72. Repeat
  73. Local i:=stdout.Find( "~n",i0 )
  74. If i=-1
  75. _stdout=stdout.Slice( i0 )
  76. Exit
  77. Endif
  78. _stdoutBuf.Add( stdout.Slice( i0,i+1 ) )
  79. i0=i+1
  80. Forever
  81. If _stdoutWaiting And Not _stdoutBuf.Empty _stdoutWaiting.Set( True )
  82. End
  83. If Not process.Start( cmd ) Return False
  84. _process=process
  85. _running=True
  86. _procOpen=True
  87. _stdoutOpen=True
  88. _stdout=""
  89. _stdoutBuf.Clear()
  90. _stdoutWaiting=Null
  91. Return True
  92. End
  93. #rem monkeydoc Reads process stdout.
  94. If an empty string is returned, the process has finished.
  95. This method may have to wait for stdout to become available, so should always be called on a fiber.
  96. #end
  97. Method ReadStdout:String()
  98. While _stdoutBuf.Empty
  99. If Not _stdoutOpen
  100. If _procOpen
  101. _stdoutWaiting=New Future<Bool>
  102. _stdoutWaiting.Get()
  103. _stdoutWaiting=Null
  104. Endif
  105. Return ""
  106. Endif
  107. _stdoutWaiting=New Future<Bool>
  108. _stdoutWaiting.Get()
  109. _stdoutWaiting=Null
  110. Wend
  111. Return _stdoutBuf.RemoveFirst()
  112. End
  113. #rem monkeydoc Writes to process stdin.
  114. #end
  115. Method WriteStdin( str:String )
  116. If Not _procOpen Return
  117. _process.WriteStdin( str )
  118. End
  119. #rem monkeydoc Terminates the process.
  120. #end
  121. Method Terminate()
  122. If Not _procOpen Return
  123. _process.Terminate()
  124. End
  125. #rem monkeydoc Writes text to the console.
  126. #end
  127. Method Write( text:String )
  128. AppendText( text )
  129. End
  130. Private
  131. Field _process:Process
  132. Field _running:Bool
  133. Field _procOpen:Bool
  134. Field _stdoutOpen:Bool
  135. Field _stdout:String
  136. Field _stdoutBuf:=New StringList
  137. Field _stdoutWaiting:Future<Bool>
  138. Method UpdateRunning()
  139. If Not _running Or _procOpen Or _stdoutOpen Return
  140. _running=False
  141. Finished( _process.ExitCode )
  142. If _stdoutWaiting _stdoutWaiting.Set( True )
  143. End
  144. End
  145. #endif