mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-08 19:47:57 +02:00
232 lines
5.5 KiB
ObjectPascal
232 lines
5.5 KiB
ObjectPascal
unit webideclient;
|
|
|
|
{$mode objfpc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, js, web;
|
|
|
|
type
|
|
TIDEClient = Class;
|
|
|
|
TIDEResponseHandler = Procedure (aCode : Integer; aCodeText : String; aPayload : TJSObject) of object;
|
|
|
|
{ TIDERequest }
|
|
|
|
TIDERequest = Class(TObject)
|
|
Private
|
|
FXHR : TJSXMLHttpRequest;
|
|
FOnResponse: TIDEResponseHandler;
|
|
Procedure ProcessResponse;
|
|
procedure DoStateChange;
|
|
Public
|
|
Constructor Create(aMethod, aURl: String; aPayLoad: TJSObject; aOnResponse: TIDEResponseHandler);
|
|
end;
|
|
|
|
{ TIDEClient }
|
|
TCommandEvent = Procedure (Sender : TObject; aCommands : TJSArray) of object;
|
|
TActionEvent = Procedure (Sender : TObject; aID : nativeint; aName : String; aPayload : TJSObject) of object;
|
|
|
|
TIDEClient = Class(TComponent)
|
|
private
|
|
FActionID : NativeInt;
|
|
FOnActionResponse: TActionEvent;
|
|
FPollID : NativeInt;
|
|
FCommandPollInterval : Integer;
|
|
FClientID: NativeInt;
|
|
FIDEURL: String;
|
|
FOnCommands: TCommandEvent;
|
|
FLastPoll : TIDERequest;
|
|
FStartPolling : Boolean;
|
|
procedure DoCommandPoll;
|
|
procedure OnActionSent(aCode: Integer; aCodeText: String; aPayload: TJSObject);
|
|
procedure OnClientRegistered(aCode: Integer; aCodeText: String; aPayload: TJSObject);
|
|
procedure OnCommandsReceived(aCode: Integer; aCodeText: String; aPayload: TJSObject);
|
|
Public
|
|
Constructor Create(aOwner : TComponent); override;
|
|
Procedure RegisterClient;
|
|
Procedure UnRegisterClient;
|
|
Procedure StartCommandPolling;
|
|
Procedure StopCommandPolling;
|
|
Function GetNextID : NativeInt;
|
|
procedure SendAction(Const aName : String; aPayLoad : TJSObject);
|
|
Property IDEURL : String read FIDEURL Write FIDEURL;
|
|
Property ClientID : nativeint read FClientID Write FClientID;
|
|
Property CommandPollInterval : Integer Read FCommandPollInterval Write FCommandPollInterval;
|
|
Property OnCommands : TCommandEvent Read FOnCommands Write FOnCommands;
|
|
Property OnActionResponse : TActionEvent Read FOnActionResponse Write FOnActionResponse;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TIDEClient }
|
|
|
|
|
|
procedure TIDEClient.DoCommandPoll;
|
|
|
|
begin
|
|
if Not Assigned(FLastPoll) then
|
|
FLastPoll:=TIDERequest.Create('Get',IDEURL+'Command/'+IntToStr(ClientID)+'/',Nil,@OnCommandsReceived);
|
|
end;
|
|
|
|
procedure TIDEClient.OnActionSent(aCode: Integer; aCodeText: String; aPayload: TJSObject);
|
|
|
|
Var
|
|
aID : NativeInt;
|
|
aName : string;
|
|
aActionPayload : TJSObject;
|
|
|
|
begin
|
|
if ((aCode div 100)=2) and Assigned(aPayload) and Assigned(OnActionResponse) then
|
|
begin
|
|
aID:=NativeInt(aPayLoad['id']);
|
|
aName:=String(aPayLoad['name']);
|
|
aActionPayLoad:=TJSObject(aPayLoad['payload']);
|
|
OnActionResponse(Self,aID,aName,aActionPayload);
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEClient.OnClientRegistered(aCode: Integer; aCodeText: String; aPayload: TJSObject);
|
|
|
|
begin
|
|
if (aCode div 100)=2 then
|
|
begin
|
|
FClientID:=NativeInt(aPayload['id']);
|
|
if FStartPolling then
|
|
StartCommandPolling;
|
|
end
|
|
else
|
|
FClientID:=0;
|
|
end;
|
|
|
|
procedure TIDEClient.OnCommandsReceived(aCode: Integer; aCodeText: String; aPayload: TJSObject);
|
|
|
|
Var
|
|
A: TJSArray;
|
|
|
|
begin
|
|
FLastPoll:=Nil;
|
|
if (aCode div 100)<>2 then
|
|
exit;
|
|
if Assigned(aPayload) and isArray(aPayload['commands']) then
|
|
begin
|
|
A:=TJSArray(aPayload['commands']);
|
|
if (A.Length>0) then
|
|
OnCommands(Self,A);
|
|
end;
|
|
end;
|
|
|
|
constructor TIDEClient.Create(aOwner: TComponent);
|
|
begin
|
|
Inherited;
|
|
FLastPoll:=Nil;
|
|
IDEURL:='http://'+Window.location.hostname+':'+Window.location.port+'/IDE/';
|
|
end;
|
|
|
|
procedure TIDEClient.RegisterClient;
|
|
|
|
Var
|
|
P : TJSObject;
|
|
Req : TIDERequest;
|
|
|
|
begin
|
|
P:=New(['url',window.locationString]);
|
|
req:=TIDERequest.Create('POST',IDEURL+'Client',P,@OnClientRegistered);
|
|
end;
|
|
|
|
procedure TIDEClient.UnRegisterClient;
|
|
|
|
Var
|
|
Req : TIDERequest;
|
|
|
|
begin
|
|
Req:=TIDERequest.Create('DELETE',IDEURL+'Client/'+IntToStr(ClientID),Nil,@OnClientRegistered);
|
|
end;
|
|
|
|
procedure TIDEClient.StartCommandPolling;
|
|
begin
|
|
if ClientID<>0 then
|
|
FPollID:=Window.setInterval(@DoCommandPoll,FCommandPollInterval)
|
|
else
|
|
FStartPolling:=True;
|
|
end;
|
|
|
|
procedure TIDEClient.StopCommandPolling;
|
|
begin
|
|
FStartPolling:=False;
|
|
if (FPollID>0) then
|
|
Window.clearInterval(FPollID);
|
|
end;
|
|
|
|
function TIDEClient.GetNextID: NativeInt;
|
|
begin
|
|
Inc(FActionID);
|
|
Result:=FActionID;
|
|
end;
|
|
|
|
procedure TIDEClient.SendAction(const aName: String; aPayLoad: TJSObject);
|
|
|
|
Var
|
|
aAction : TJSObject;
|
|
aID : NativeInt;
|
|
req: TIDERequest;
|
|
|
|
begin
|
|
aID:=GetNextID;
|
|
aAction:=New(['id',aID,
|
|
'name',aName,
|
|
'payload',aPayLoad]);
|
|
req:=TIDERequest.Create('POST',IDEURL+'Action/'+IntToStr(ClientID)+'/'+IntToStr(aID),aAction,@OnActionSent);
|
|
end;
|
|
|
|
{ TIDERequest }
|
|
|
|
procedure TIDERequest.ProcessResponse;
|
|
|
|
var
|
|
P : TJSObject;
|
|
|
|
begin
|
|
if ((FXHR.Status div 100)=2) and (FXHR.ResponseHeaders['Content-Type']='application/json') then
|
|
P:=TJSJSON.parseObject(FXHR.responseText)
|
|
else
|
|
P:=Nil;
|
|
if Assigned(FOnResponse) then
|
|
FOnResponse(FXHR.Status,FXHR.StatusText,P);
|
|
end;
|
|
|
|
procedure TIDERequest.DoStateChange;
|
|
begin
|
|
case FXHR.readyState of
|
|
TJSXMLHttpRequest.DONE :
|
|
begin
|
|
if Assigned(FOnResponse) then
|
|
ProcessResponse;
|
|
Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
constructor TIDERequest.Create(aMethod, aURl: String; aPayLoad: TJSObject; aOnResponse: TIDEResponseHandler);
|
|
|
|
Var
|
|
S : String;
|
|
|
|
begin
|
|
FOnResponse:=aOnResponse;
|
|
FXHR:=TJSXMLHttpRequest.New;
|
|
FXHR.open(aMethod,aURL);
|
|
if assigned(aPayload) then
|
|
S:=TJSJSON.Stringify(aPayload)
|
|
else
|
|
S:='';
|
|
FXHR.setRequestHeader('Content-Type','application/json');
|
|
FXHR.onreadystatechange:=@DoStateChange;
|
|
FXHR.send(S);
|
|
end;
|
|
|
|
|
|
end.
|
|
|