GLS.ScriptBase.pas 6.3 KB

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