GLScriptPython.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. (*
  5. Python implementation for the GLScene scripting layer.
  6. This unit is experimental.
  7. *)
  8. unit GLScriptPython;
  9. interface
  10. uses
  11. System.Classes,
  12. System.SysUtils,
  13. XCollection,
  14. GLScriptBase,
  15. GLManager,
  16. PythonEngine;
  17. type
  18. (* This class only adds manager registration logic to the TPythonEngine
  19. class to enable the XCollection items (ie. TGLScriptPython) retain it's
  20. assigned compiler from design to run -time. *)
  21. TGLPythonEngine = class(TPythonEngine)
  22. public
  23. constructor Create(AOnwer : TComponent); override;
  24. destructor Destroy; override;
  25. end;
  26. { Implements Python scripting functionality through the abstracted GLScriptBase }
  27. TGLScriptPython = class(TGLScriptBase)
  28. private
  29. FEngine : TGLPythonEngine;
  30. FEngineName : String;
  31. FCompiled,
  32. FStarted : Boolean;
  33. protected
  34. procedure SetEngine(const Value : TGLPythonEngine);
  35. procedure ReadFromFiler(reader : TReader); override;
  36. procedure WriteToFiler(writer : TWriter); override;
  37. procedure Loaded; override;
  38. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  39. function GetState : TGLScriptState; override;
  40. public
  41. destructor Destroy; override;
  42. procedure Assign(Source: TPersistent); override;
  43. procedure Compile; override;
  44. procedure Start; override;
  45. procedure Stop; override;
  46. procedure Execute; override;
  47. procedure Invalidate; override;
  48. function Call(aName : String; aParams : array of Variant) : Variant; override;
  49. class function FriendlyName : String; override;
  50. class function FriendlyDescription : String; override;
  51. class function ItemCategory : String; override;
  52. published
  53. property Engine : TGLPythonEngine read FEngine write SetEngine;
  54. end;
  55. procedure Register;
  56. // --------------------------------------------------
  57. implementation
  58. // --------------------------------------------------
  59. // ----------
  60. // ---------- TGLPythonEngine ----------
  61. // ----------
  62. constructor TGLPythonEngine.Create(AOnwer : TComponent);
  63. begin
  64. inherited;
  65. RegisterManager(Self);
  66. end;
  67. destructor TGLPythonEngine.Destroy;
  68. begin
  69. DeregisterManager(Self);
  70. inherited;
  71. end;
  72. // ---------------
  73. // --------------- TGLScriptPython ---------------
  74. // ---------------
  75. destructor TGLScriptPython.Destroy;
  76. begin
  77. Invalidate;
  78. inherited;
  79. end;
  80. procedure TGLScriptPython.Assign(Source: TPersistent);
  81. begin
  82. inherited;
  83. if Source is TGLScriptPython then begin
  84. Engine:=TGLScriptPython(Source).Engine;
  85. end;
  86. end;
  87. procedure TGLScriptPython.ReadFromFiler(reader : TReader);
  88. var
  89. archiveVersion : Integer;
  90. begin
  91. inherited;
  92. archiveVersion:=reader.ReadInteger;
  93. Assert(archiveVersion = 0);
  94. with reader do begin
  95. FEngineName:=ReadString;
  96. end;
  97. end;
  98. procedure TGLScriptPython.WriteToFiler(writer : TWriter);
  99. begin
  100. inherited;
  101. writer.WriteInteger(0); // archiveVersion
  102. with writer do begin
  103. if Assigned(FEngine) then
  104. WriteString(FEngine.GetNamePath)
  105. else
  106. WriteString('');
  107. end;
  108. end;
  109. procedure TGLScriptPython.Loaded;
  110. var
  111. temp : TComponent;
  112. begin
  113. inherited;
  114. if FEngineName<>'' then begin
  115. temp:=FindManager(TGLPythonEngine, FEngineName);
  116. if Assigned(temp) then
  117. Engine:=TGLPythonEngine(temp);
  118. FEngineName:='';
  119. end;
  120. end;
  121. procedure TGLScriptPython.Notification(AComponent: TComponent; Operation: TOperation);
  122. begin
  123. if (AComponent = Engine) and (Operation = opRemove) then
  124. Engine:=nil;
  125. end;
  126. class function TGLScriptPython.FriendlyName : String;
  127. begin
  128. Result:='TGLScriptPython';
  129. end;
  130. class function TGLScriptPython.FriendlyDescription : String;
  131. begin
  132. Result:='Python script';
  133. end;
  134. class function TGLScriptPython.ItemCategory : String;
  135. begin
  136. Result:='';
  137. end;
  138. procedure TGLScriptPython.Compile;
  139. begin
  140. Invalidate;
  141. if Assigned(Engine) then begin
  142. Engine.ExecStrings(Text);
  143. FCompiled:=True;
  144. FStarted:=False;
  145. end else
  146. raise Exception.Create('No engine assigned!');
  147. end;
  148. procedure TGLScriptPython.Execute;
  149. begin
  150. Compile;
  151. end;
  152. procedure TGLScriptPython.Invalidate;
  153. begin
  154. FStarted:=False;
  155. FCompiled:=False;
  156. end;
  157. procedure TGLScriptPython.Start;
  158. begin
  159. Compile;
  160. FStarted:=True;
  161. end;
  162. procedure TGLScriptPython.Stop;
  163. begin
  164. FStarted:=False;
  165. end;
  166. function TGLScriptPython.Call(aName: String;
  167. aParams: array of Variant) : Variant;
  168. var
  169. func : PPyObject;
  170. args : array of TVarRec;
  171. i : Integer;
  172. begin
  173. if State = ssUncompiled then
  174. Start;
  175. if State = ssRunning then begin
  176. func:=Engine.FindFunction('__main__', aName);
  177. if Assigned(func) then
  178. if Length(aParams)>0 then begin
  179. SetLength(args, Length(aParams));
  180. for i:=0 to Length(aParams)-1 do begin
  181. args[i].VType:=vtVariant;
  182. args[i].VVariant:=@aParams[i];
  183. end;
  184. Result:=Engine.EvalFunction(func, args);
  185. end else
  186. Result:=Engine.EvalFunctionNoArgs(func);
  187. end;
  188. end;
  189. procedure TGLScriptPython.SetEngine(const Value : TGLPythonEngine);
  190. begin
  191. if Value<>FEngine then begin
  192. FEngine:=Value;
  193. Invalidate;
  194. end;
  195. end;
  196. function TGLScriptPython.GetState : TGLScriptState;
  197. begin
  198. Result:=ssUncompiled;
  199. if Assigned(Engine) and FCompiled and FStarted then
  200. Result:=ssRunning;
  201. end;
  202. procedure Register;
  203. begin
  204. RegisterClasses([TGLPythonEngine, TGLScriptPython]);
  205. RegisterComponents('GLScene Python', [TGLPythonEngine]);
  206. end;
  207. // --------------------------------------------------
  208. initialization
  209. // --------------------------------------------------
  210. RegisterXCollectionItemClass(TGLScriptPython);
  211. // --------------------------------------------------
  212. finalization
  213. // --------------------------------------------------
  214. UnregisterXCollectionItemClass(TGLScriptPython);
  215. end.