GLDWSObjects.pas 6.6 KB

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