DWS.Objects.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //
  2. // The graphics rendering engine GLScene http://glscene.org
  3. //
  4. unit DWS.Objects;
  5. (*
  6. Base classes and logic for DelphiWebScript enabled objects
  7. in GLScene for vcl https://bitbucket.org/egrange/dwscript/src/master/
  8. *)
  9. interface
  10. uses
  11. System.Classes,
  12. System.SysUtils,
  13. GLS.OpenGLTokens,
  14. GLS.Scene,
  15. GLS.XCollection,
  16. GLS.BaseClasses,
  17. GLS.Manager,
  18. DWS.Script,
  19. dwsComp,
  20. dwsExprs,
  21. dwsSymbols;
  22. type
  23. (* A DelphiWebScript enabled behaviour. This behaviour also calls
  24. on the OnProgress and OnBeginProgram procedures in the script if
  25. they are found. Once compiled and executed the program remains
  26. active until killed, deactivated or the script is invalidated. *)
  27. TGLDWSActiveBehaviour = class(TGLBehaviour)
  28. private
  29. FActive: Boolean;
  30. FScript: TStringList;
  31. FDWSProgram: TProgram;
  32. FCompiler: TGLDelphiWebScript;
  33. FCompilerName: String;
  34. procedure SetActive(const Value: Boolean);
  35. procedure SetScript(const Value: TStringList);
  36. procedure SetCompiler(const Value: TGLDelphiWebScript);
  37. procedure CompileProgram;
  38. procedure BeginProgram;
  39. procedure EndProgram;
  40. procedure KillProgram;
  41. protected
  42. procedure WriteToFiler(writer: TWriter); override;
  43. procedure ReadFromFiler(reader: TReader); override;
  44. procedure Loaded; override;
  45. public
  46. constructor Create(AOwner: TXCollection); override;
  47. destructor Destroy; override;
  48. class function FriendlyName: String; override;
  49. procedure DoProgress(const ProgressTimes: TGLProgressTimes); override;
  50. procedure InvalidateScript;
  51. property DWSProgram: TProgram read FDWSProgram;
  52. published
  53. property Active: Boolean read FActive write SetActive;
  54. property Script: TStringList read FScript write SetScript;
  55. property Compiler: TGLDelphiWebScript read FCompiler write SetCompiler;
  56. end;
  57. procedure Register;
  58. // --------------------------------------------------
  59. implementation
  60. // --------------------------------------------------
  61. // ----------
  62. // ---------- Miscellaneous ----------
  63. // ----------
  64. procedure Register;
  65. begin
  66. RegisterClasses([TGLDWSActiveBehaviour]);
  67. end;
  68. // ----------
  69. // ---------- TGLDWSActiveBehaviour ----------
  70. // ----------
  71. constructor TGLDWSActiveBehaviour.Create(AOwner: TXCollection);
  72. begin
  73. inherited;
  74. FScript := TStringList.Create;
  75. end;
  76. destructor TGLDWSActiveBehaviour.Destroy;
  77. begin
  78. KillProgram;
  79. FScript.Free;
  80. inherited;
  81. end;
  82. class function TGLDWSActiveBehaviour.FriendlyName: String;
  83. begin
  84. Result := 'DWS Active Script';
  85. end;
  86. procedure TGLDWSActiveBehaviour.DoProgress(const ProgressTimes: TGLProgressTimes);
  87. var
  88. Symbol: TSymbol;
  89. begin
  90. inherited;
  91. if Assigned(FDWSProgram) then
  92. begin
  93. if FDWSProgram.ProgramState = psRunning then
  94. begin
  95. Symbol := DWSProgram.Table.FindSymbol('OnProgress');
  96. if Assigned(Symbol) then
  97. if Symbol is TFuncSymbol then
  98. DWSProgram.Info.Func['OnProgress']
  99. .Call([ProgressTimes.newTime, ProgressTimes.deltaTime]);
  100. end;
  101. end;
  102. end;
  103. procedure TGLDWSActiveBehaviour.Loaded;
  104. var
  105. temp: TComponent;
  106. begin
  107. inherited;
  108. if FCompilerName <> '' then
  109. begin
  110. temp := FindManager(TGLDelphiWebScript, FCompilerName);
  111. if Assigned(temp) then
  112. Compiler := TGLDelphiWebScript(temp);
  113. FCompilerName := '';
  114. CompileProgram;
  115. if Active then
  116. BeginProgram;
  117. end;
  118. end;
  119. procedure TGLDWSActiveBehaviour.ReadFromFiler(reader: TReader);
  120. begin
  121. inherited;
  122. with reader do
  123. begin
  124. Assert(ReadInteger = 0); // Archive version
  125. Active := ReadBoolean;
  126. FCompilerName := ReadString;
  127. Script.Text := ReadString;
  128. end;
  129. end;
  130. procedure TGLDWSActiveBehaviour.WriteToFiler(writer: TWriter);
  131. begin
  132. inherited;
  133. with writer do
  134. begin
  135. WriteInteger(0); // Archive version
  136. WriteBoolean(FActive);
  137. if Assigned(FCompiler) then
  138. WriteString(FCompiler.GetNamePath)
  139. else
  140. WriteString('');
  141. WriteString(Script.Text);
  142. end;
  143. end;
  144. procedure TGLDWSActiveBehaviour.CompileProgram;
  145. begin
  146. if Assigned(Compiler) then
  147. begin
  148. KillProgram;
  149. FDWS2Program := Compiler.Compile(Script.Text);
  150. if Active then
  151. BeginProgram;
  152. end;
  153. end;
  154. procedure TGLDWSActiveBehaviour.BeginProgram;
  155. var
  156. Symbol: TSymbol;
  157. ObjectID: Variant;
  158. Obj: TGLBaseSceneObject;
  159. begin
  160. if Assigned(DWSProgram) then
  161. begin
  162. if DWSProgram.ProgramState = psReadyToRun then
  163. begin
  164. DWSProgram.BeginProgram;
  165. if FDWSProgram.ProgramState = psRunning then
  166. begin
  167. Symbol := DWSProgram.Table.FindSymbol('OnBeginProgram');
  168. if Assigned(Symbol) then
  169. if Symbol is TFuncSymbol then
  170. begin
  171. Obj := OwnerBaseSceneObject;
  172. if Assigned(Obj) then
  173. begin
  174. ObjectID := DWSProgram.Info.RegisterExternalObject(Obj,
  175. False, False);
  176. DWSProgram.Info.Func['OnBeginProgram'].Call([ObjectID]);
  177. end;
  178. end;
  179. end;
  180. end;
  181. end;
  182. end;
  183. procedure TGLDWSActiveBehaviour.EndProgram;
  184. begin
  185. if Assigned(DWSProgram) then
  186. begin
  187. if DWSProgram.ProgramState = psRunning then
  188. DWSProgram.EndProgram;
  189. end;
  190. end;
  191. procedure TGLDWSActiveBehaviour.KillProgram;
  192. begin
  193. if Assigned(DWSProgram) then
  194. begin
  195. EndProgram;
  196. FreeAndNil(FDWSProgram);
  197. end;
  198. end;
  199. procedure TGLDWSActiveBehaviour.InvalidateScript;
  200. begin
  201. KillProgram;
  202. CompileProgram;
  203. end;
  204. procedure TGLDWSActiveBehaviour.SetActive(const Value: Boolean);
  205. begin
  206. if Value <> FActive then
  207. begin
  208. EndProgram;
  209. FActive := Value;
  210. if Active then
  211. BeginProgram;
  212. end;
  213. end;
  214. procedure TGLDWSActiveBehaviour.SetScript(const Value: TStringList);
  215. begin
  216. if Assigned(Value) then
  217. begin
  218. KillProgram;
  219. FScript.Assign(Value);
  220. if Assigned(Compiler) then
  221. begin
  222. CompileProgram;
  223. if Active then
  224. BeginProgram;
  225. end;
  226. end;
  227. end;
  228. procedure TGLDWSActiveBehaviour.SetCompiler(const Value: TGLDelphiWebScript);
  229. begin
  230. if Value <> FCompiler then
  231. begin
  232. if Assigned(FCompiler) then
  233. KillProgram;
  234. FCompiler := Value;
  235. if Assigned(FCompiler) then
  236. begin
  237. RegisterManager(FCompiler);
  238. CompileProgram;
  239. if Active then
  240. BeginProgram;
  241. end;
  242. end;
  243. end;
  244. // --------------------------------------------------
  245. initialization
  246. // --------------------------------------------------
  247. RegisterXCollectionItemClass(TGLDWSActiveBehaviour);
  248. // --------------------------------------------------
  249. finalization
  250. // --------------------------------------------------
  251. UnregisterXCollectionItemClass(TGLDWSActiveBehaviour);
  252. end.