Menu

[r59]: / trunk / src / uSE2ScriptThread.pas  Maximize  Restore  History

Download this file

203 lines (164 with data), 4.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
unit uSE2ScriptThread;
{$INCLUDE ScriptEngine.inc}
interface
{$IFNDEF SEII_NO_SCRIPT_THREAD}
uses
Classes, SysUtils, uSE2ExecutionContext, SyncObjs;
type
ESE2ThreadException = class(Exception);
ESE2ThreadTerminate = class(ESE2ThreadException);
TThreadState = (tsWaiting, tsExecuting, tsSuspended, tsFinished);
TSE2ScriptThread = class(TThread)
private
FStateSection : SyncObjs.TCriticalSection;
FState : TThreadState;
FExecutePos : Pointer;
FInstance : Pointer;
FScriptContext : Pointer;
FContext : TSE2ExecutionContext;
FOnScriptTerminate : TNotifyEvent;
FDoTerminate : boolean;
protected
procedure BeforeExecutingEvent(Sender: TObject);
procedure TerminatedEvent(Sender: TObject);
function GetAffinity: cardinal;
procedure SetAffinity(value: cardinal);
procedure SetState(value: TThreadState);
function GetState: TThreadState;
procedure Execute; override;
procedure FreeScriptContext;
public
constructor Create(ARunTime, AContext: Pointer); virtual;
destructor Destroy; override;
procedure Terminate; reintroduce;
property Affinity : cardinal read GetAffinity write SetAffinity;
property Context : Pointer read FScriptContext;
property State : TThreadState read GetState;
property OnDone : TNotifyEvent read FOnScriptTerminate write FOnScriptTerminate;
end;
{$ENDIF}
implementation
{$IFNDEF SEII_NO_SCRIPT_THREAD}
uses
uSE2RunTime, uSE2OpCode, uSE2Consts
{$IFDEF MSWINDOWS}
, Windows
{$ENDIF}
;
{ TScriptThread }
procedure TSE2ScriptThread.BeforeExecutingEvent(Sender: TObject);
begin
if FDoTerminate then
begin
FDoTerminate := False;
raise ESE2ThreadTerminate.Create('Terminal signal raised');
end;
end;
constructor TSE2ScriptThread.Create(ARunTime, AContext: Pointer);
var setThreadPtr: Pointer;
begin
if AContext = nil then
raise ESE2NullReferenceError.Create('Script runtime not assigned');
if AContext = nil then
raise ESE2NullReferenceError.Create('Script execution context can not be nil');
inherited Create(True);
FreeOnTerminate := False;
FInstance := ARunTime;
FScriptContext := AContext;
FContext := TSE2ExecutionContext.Create;
if FInstance <> nil then
TSE2RunTime(FInstance).AddThreadContext(@FContext);
FContext.ExecutionData := TSE2RunTime(ARunTime).ExecutionData;
FContext.OnBeforeOperation := BeforeExecutingEvent;
inherited OnTerminate := TerminatedEvent;
FState := tsWaiting;
setThreadPtr := FContext.ExecutionData.CodeAccess.FindMethod('TExecutionContext.__SetThread', C_SE2ThreadingUnit, [pmIn, pmIn], [btObject, btObject]);
if setThreadPtr <> nil then
FContext.Call(setThreadPtr, [AContext, Self]);
FExecutePos := FContext.ExecutionData.CodeAccess.FindMethod('TExecutionContext.Execute', C_SE2ThreadingUnit, [pmIn], [btObject]);
if FExecutePos = nil then
raise ESE2ThreadException.Create('Execute-Method not found');
FStateSection := SyncObjs.TCriticalSection.Create;
end;
destructor TSE2ScriptThread.Destroy;
begin
FreeScriptContext;
FStateSection.Free;
inherited;
end;
procedure TSE2ScriptThread.Execute;
begin
try
FContext.Call(FExecutePos, [FScriptContext]);
finally
SetState(tsFinished);
end;
end;
procedure TSE2ScriptThread.FreeScriptContext;
begin
if FContext <> nil then
begin
if FInstance <> nil then
TSE2RunTime(FInstance).RemoveThreadContext(@FContext);
FreeAndNil(FContext);
end;
end;
{$Warnings off}
function TSE2ScriptThread.GetAffinity: cardinal;
{$IFDEF MSWINDOWS}
var tmp: cardinal;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
GetProcessAffinityMask(Self.Handle, result, tmp);
{$ELSE}
result := $FFFFFFFF;
{$ENDIF}
end;
{$Warnings on}
function TSE2ScriptThread.GetState: TThreadState;
begin
result := tsWaiting;
try
FStateSection.Enter;
try
result := FState;
finally
FStateSection.Leave;
end;
except
end;
end;
procedure TSE2ScriptThread.SetAffinity(value: cardinal);
begin
{$IFDEF MSWINDOWS}
SetThreadAffinityMask(Self.Handle, value);
{$ENDIF}
end;
procedure TSE2ScriptThread.SetState(value: TThreadState);
begin
try
FStateSection.Enter;
try
FState := value;
finally
FStateSection.Leave;
end;
except
end;
end;
procedure TSE2ScriptThread.Terminate;
begin
FDoTerminate := True;
end;
procedure TSE2ScriptThread.TerminatedEvent(Sender: TObject);
begin
if Assigned(Self.OnDone) then
try
Self.OnDone(TObject(FScriptContext));
except
end;
FreeScriptContext;
end;
{$ENDIF}
end.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.