DWSx.Objects.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. //
  2. // The graphics engine GXScene https://github.com/glscene
  3. //
  4. unit DWSx.Objects;
  5. (*
  6. Base classes and logic for DelphiWebScript enabled objects
  7. *)
  8. interface
  9. uses
  10. Winapi.OpenGL,
  11. Winapi.OpenGLext,
  12. System.Classes,
  13. System.SysUtils,
  14. GXS.Scene,
  15. GXS.XCollection,
  16. GXS.BaseClasses,
  17. GXS.Manager,
  18. DWSx.Script,
  19. dwsComp, // dwxComp,...
  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. TdwxActiveBehaviour = class(TgxBehaviour)
  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: TgxDelphiWebScript);
  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: TgxProgressTimes); 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. // ----------
  65. // ---------- TGLDWSActiveBehaviour ----------
  66. // ----------
  67. constructor TGLDWSActiveBehaviour.Create(AOwner: TXCollection);
  68. begin
  69. inherited;
  70. FScript := TStringList.Create;
  71. end;
  72. destructor TGLDWSActiveBehaviour.Destroy;
  73. begin
  74. KillProgram;
  75. FScript.Free;
  76. inherited;
  77. end;
  78. class function TGLDWSActiveBehaviour.FriendlyName: String;
  79. begin
  80. Result := 'DWS Active Script';
  81. end;
  82. procedure TGLDWSActiveBehaviour.DoProgress(const ProgressTimes: TGLProgressTimes);
  83. var
  84. Symbol: TSymbol;
  85. begin
  86. inherited;
  87. if Assigned(FDWSProgram) then
  88. begin
  89. if FDWSProgram.ProgramState = psRunning then
  90. begin
  91. Symbol := DWSProgram.Table.FindSymbol('OnProgress');
  92. if Assigned(Symbol) then
  93. if Symbol is TFuncSymbol then
  94. DWSProgram.Info.Func['OnProgress']
  95. .Call([ProgressTimes.newTime, ProgressTimes.deltaTime]);
  96. end;
  97. end;
  98. end;
  99. procedure TGLDWSActiveBehaviour.Loaded;
  100. var
  101. temp: TComponent;
  102. begin
  103. inherited;
  104. if FCompilerName <> '' then
  105. begin
  106. temp := FindManager(TGLDelphiWebScript, FCompilerName);
  107. if Assigned(temp) then
  108. Compiler := TGLDelphiWebScript(temp);
  109. FCompilerName := '';
  110. CompileProgram;
  111. if Active then
  112. BeginProgram;
  113. end;
  114. end;
  115. procedure TGLDWSActiveBehaviour.ReadFromFiler(reader: TReader);
  116. begin
  117. inherited;
  118. with reader do
  119. begin
  120. Assert(ReadInteger = 0); // Archive version
  121. Active := ReadBoolean;
  122. FCompilerName := ReadString;
  123. Script.Text := ReadString;
  124. end;
  125. end;
  126. procedure TGLDWSActiveBehaviour.WriteToFiler(writer: TWriter);
  127. begin
  128. inherited;
  129. with writer do
  130. begin
  131. WriteInteger(0); // Archive version
  132. WriteBoolean(FActive);
  133. if Assigned(FCompiler) then
  134. WriteString(FCompiler.GetNamePath)
  135. else
  136. WriteString('');
  137. WriteString(Script.Text);
  138. end;
  139. end;
  140. procedure TGLDWSActiveBehaviour.CompileProgram;
  141. begin
  142. if Assigned(Compiler) then
  143. begin
  144. KillProgram;
  145. FDWS2Program := Compiler.Compile(Script.Text);
  146. if Active then
  147. BeginProgram;
  148. end;
  149. end;
  150. procedure TGLDWSActiveBehaviour.BeginProgram;
  151. var
  152. Symbol: TSymbol;
  153. ObjectID: Variant;
  154. Obj: TGLBaseSceneObject;
  155. begin
  156. if Assigned(DWSProgram) then
  157. begin
  158. if DWSProgram.ProgramState = psReadyToRun then
  159. begin
  160. DWSProgram.BeginProgram;
  161. if FDWSProgram.ProgramState = psRunning then
  162. begin
  163. Symbol := DWSProgram.Table.FindSymbol('OnBeginProgram');
  164. if Assigned(Symbol) then
  165. if Symbol is TFuncSymbol then
  166. begin
  167. Obj := OwnerBaseSceneObject;
  168. if Assigned(Obj) then
  169. begin
  170. ObjectID := DWSProgram.Info.RegisterExternalObject(Obj,
  171. False, False);
  172. DWSProgram.Info.Func['OnBeginProgram'].Call([ObjectID]);
  173. end;
  174. end;
  175. end;
  176. end;
  177. end;
  178. end;
  179. procedure TGLDWSActiveBehaviour.EndProgram;
  180. begin
  181. if Assigned(DWSProgram) then
  182. begin
  183. if DWSProgram.ProgramState = psRunning then
  184. DWSProgram.EndProgram;
  185. end;
  186. end;
  187. procedure TGLDWSActiveBehaviour.KillProgram;
  188. begin
  189. if Assigned(DWSProgram) then
  190. begin
  191. EndProgram;
  192. FreeAndNil(FDWSProgram);
  193. end;
  194. end;
  195. procedure TGLDWSActiveBehaviour.InvalidateScript;
  196. begin
  197. KillProgram;
  198. CompileProgram;
  199. end;
  200. procedure TGLDWSActiveBehaviour.SetActive(const Value: Boolean);
  201. begin
  202. if Value <> FActive then
  203. begin
  204. EndProgram;
  205. FActive := Value;
  206. if Active then
  207. BeginProgram;
  208. end;
  209. end;
  210. procedure TGLDWSActiveBehaviour.SetScript(const Value: TStringList);
  211. begin
  212. if Assigned(Value) then
  213. begin
  214. KillProgram;
  215. FScript.Assign(Value);
  216. if Assigned(Compiler) then
  217. begin
  218. CompileProgram;
  219. if Active then
  220. BeginProgram;
  221. end;
  222. end;
  223. end;
  224. procedure TdwxActiveBehaviour.SetCompiler(const Value: TGLDelphiWebScript);
  225. begin
  226. if Value <> FCompiler then
  227. begin
  228. if Assigned(FCompiler) then
  229. KillProgram;
  230. FCompiler := Value;
  231. if Assigned(FCompiler) then
  232. begin
  233. RegisterManager(FCompiler);
  234. CompileProgram;
  235. if Active then
  236. BeginProgram;
  237. end;
  238. end;
  239. end;
  240. procedure Register;
  241. begin
  242. RegisterClasses([TdwxActiveBehaviour]);
  243. end;
  244. // --------------------------------------------------
  245. initialization
  246. // --------------------------------------------------
  247. RegisterXCollectionItemClass(TdwxActiveBehaviour);
  248. // --------------------------------------------------
  249. finalization
  250. // --------------------------------------------------
  251. UnregisterXCollectionItemClass(TdwxActiveBehaviour);
  252. end.