GXS.ScriptBase.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //
  2. // The graphics engine GXScene https://github.com/glscene
  3. //
  4. unit GXS.ScriptBase;
  5. (*
  6. An abstract scripting interface for GLScene
  7. This unit provides the base methods for compiling and executing scripts as
  8. well as calling scripted functions. No scripting APIs are implemented here,
  9. only abstracted functions.
  10. *)
  11. interface
  12. uses
  13. System.Classes,
  14. GXS.XCollection;
  15. type
  16. TgxScriptState = (ssUncompiled, // The script has yet to be compiled.
  17. ssCompileErrors, // Errors occurred while compiling.
  18. ssCompiled, // The script has been compiled and is
  19. // ready to be executed/started.
  20. ssRunningErrors, // Errors occured while the script was
  21. // running.
  22. ssRunning); // The script is currently active and
  23. // is running without error.
  24. (* The base script class that defines the abstract functions and properties.
  25. Don't use this class directly, use the script classes descended from this
  26. base class. *)
  27. TgxScriptBase = class(TXCollectionItem)
  28. private
  29. FText: TStringList;
  30. FDescription: String;
  31. FErrors: TStringList; // not persistent
  32. protected
  33. procedure WriteToFiler(writer: TWriter); override;
  34. procedure ReadFromFiler(reader: TReader); override;
  35. function GetState: TgxScriptState; virtual; abstract;
  36. procedure SetText(const Value: TStringList);
  37. procedure Notification(AComponent: TComponent;
  38. Operation: TOperation); virtual;
  39. public
  40. constructor Create(aOwner: TXCollection); override;
  41. destructor Destroy; override;
  42. procedure Assign(Source: TPersistent); override;
  43. procedure Compile; virtual; abstract;
  44. procedure Start; virtual; abstract;
  45. procedure Stop; virtual; abstract;
  46. procedure Execute; virtual; abstract;
  47. procedure Invalidate; virtual; abstract;
  48. function Call(aName: String; aParams: array of Variant): Variant;
  49. virtual; abstract;
  50. property Errors: TStringList read FErrors;
  51. property State: TgxScriptState read GetState;
  52. published
  53. property Text: TStringList read FText write SetText;
  54. property Description: String read FDescription write FDescription;
  55. end;
  56. // XCollection descendant for storing and handling scripts.
  57. TgxScripts = class(TXCollection)
  58. protected
  59. function GetItems(index: Integer): TgxScriptBase;
  60. public
  61. procedure Assign(Source: TPersistent); override;
  62. class function ItemsClass: TXCollectionItemClass; override;
  63. function CanAdd(aClass: TXCollectionItemClass): Boolean; override;
  64. property Items[index: Integer]: TgxScriptBase read GetItems; default;
  65. end;
  66. (* Encapsulation of the scripts XCollection to help with script handling at
  67. design-time. Links the scripts to Delphi's persistence model. *)
  68. TgxScriptLibrary = class(TComponent)
  69. private
  70. FScripts: TgxScripts;
  71. protected
  72. procedure DefineProperties(Filer: TFiler); override;
  73. procedure WriteScriptsData(Stream: TStream);
  74. procedure ReadScriptsData(Stream: TStream);
  75. procedure Loaded; override;
  76. procedure Notification(AComponent: TComponent;
  77. Operation: TOperation); override;
  78. public
  79. constructor Create(aOwner: TComponent); override;
  80. destructor Destroy; override;
  81. published
  82. property Scripts: TgxScripts read FScripts;
  83. end;
  84. // ------------------------------------------
  85. implementation
  86. // ------------------------------------------
  87. // ---------------
  88. // --------------- TgxScriptBase ---------------
  89. // ---------------
  90. constructor TgxScriptBase.Create(aOwner: TXCollection);
  91. begin
  92. inherited;
  93. FText := TStringList.Create;
  94. FErrors := TStringList.Create;
  95. end;
  96. destructor TgxScriptBase.Destroy;
  97. begin
  98. FText.Free;
  99. FErrors.Free;
  100. inherited;
  101. end;
  102. procedure TgxScriptBase.Assign(Source: TPersistent);
  103. begin
  104. inherited;
  105. if Source is TgxScriptBase then
  106. begin
  107. Text.Assign(TgxScriptBase(Source).Text);
  108. Description := TgxScriptBase(Source).Description;
  109. end;
  110. end;
  111. procedure TgxScriptBase.ReadFromFiler(reader: TReader);
  112. var
  113. archiveVersion: Integer;
  114. begin
  115. inherited;
  116. archiveVersion := reader.ReadInteger;
  117. Assert(archiveVersion = 0);
  118. with reader do
  119. begin
  120. FText.Text := ReadString;
  121. FDescription := ReadString;
  122. end;
  123. end;
  124. procedure TgxScriptBase.WriteToFiler(writer: TWriter);
  125. begin
  126. inherited;
  127. writer.WriteInteger(0);
  128. with writer do
  129. begin
  130. WriteString(FText.Text);
  131. WriteString(FDescription);
  132. end;
  133. end;
  134. procedure TgxScriptBase.SetText(const Value: TStringList);
  135. begin
  136. Text.Assign(Value);
  137. end;
  138. procedure TgxScriptBase.Notification(AComponent: TComponent;
  139. Operation: TOperation);
  140. begin
  141. // Virtual
  142. end;
  143. // ---------------
  144. // --------------- TgxScripts ---------------
  145. // ---------------
  146. procedure TgxScripts.Assign(Source: TPersistent);
  147. begin
  148. inherited;
  149. // Nothing yet
  150. end;
  151. function TgxScripts.GetItems(index: Integer): TgxScriptBase;
  152. begin
  153. Result := TgxScriptBase(inherited GetItems(index));
  154. end;
  155. class function TgxScripts.ItemsClass: TXCollectionItemClass;
  156. begin
  157. Result := TgxScriptBase;
  158. end;
  159. function TgxScripts.CanAdd(aClass: TXCollectionItemClass): Boolean;
  160. begin
  161. Result := aClass.InheritsFrom(TgxScriptBase);
  162. end;
  163. // ---------------
  164. // --------------- TgxScriptLibrary ---------------
  165. // ---------------
  166. constructor TgxScriptLibrary.Create(aOwner: TComponent);
  167. begin
  168. inherited;
  169. FScripts := TgxScripts.Create(Self);
  170. end;
  171. destructor TgxScriptLibrary.Destroy;
  172. begin
  173. FScripts.Free;
  174. inherited;
  175. end;
  176. procedure TgxScriptLibrary.DefineProperties(Filer: TFiler);
  177. begin
  178. inherited;
  179. Filer.DefineBinaryProperty('ScriptsData', ReadScriptsData, WriteScriptsData,
  180. (Scripts.Count > 0));
  181. end;
  182. procedure TgxScriptLibrary.WriteScriptsData(Stream: TStream);
  183. var
  184. writer: TWriter;
  185. begin
  186. writer := TWriter.Create(Stream, 16384);
  187. try
  188. Scripts.WriteToFiler(writer);
  189. finally
  190. writer.Free;
  191. end;
  192. end;
  193. procedure TgxScriptLibrary.ReadScriptsData(Stream: TStream);
  194. var
  195. reader: TReader;
  196. begin
  197. reader := TReader.Create(Stream, 16384);
  198. try
  199. Scripts.ReadFromFiler(reader);
  200. finally
  201. reader.Free;
  202. end;
  203. end;
  204. procedure TgxScriptLibrary.Loaded;
  205. begin
  206. inherited;
  207. Scripts.Loaded;
  208. end;
  209. procedure TgxScriptLibrary.Notification(AComponent: TComponent;
  210. Operation: TOperation);
  211. var
  212. i: Integer;
  213. begin
  214. if Assigned(Scripts) then
  215. for i := 0 to Scripts.Count - 1 do
  216. Scripts[i].Notification(AComponent, Operation);
  217. inherited;
  218. end;
  219. // -------------------------------------
  220. initialization
  221. // -------------------------------------
  222. RegisterClasses([TgxScriptLibrary, TgxScripts, TgxScriptBase]);
  223. end.