mirror of https://github.com/red-prig/fpPS4.git
396 lines
7.5 KiB
Plaintext
396 lines
7.5 KiB
Plaintext
unit host_ipc_interface;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes,
|
|
CharStream,
|
|
murmurhash,
|
|
HAMT,
|
|
sys_event,
|
|
game_info;
|
|
|
|
const
|
|
iRESULT=0;
|
|
|
|
{
|
|
type
|
|
t_mtype=(
|
|
iRESULT,
|
|
iERROR,
|
|
iKEV_CHANGE,
|
|
iKEV_EVENT,
|
|
iMOUNT,
|
|
iMAIN_WINDOWS,
|
|
iCAPTION_FPS
|
|
);
|
|
}
|
|
|
|
type
|
|
TOnMessage=function(mlen:DWORD;buf:Pointer):Ptruint of object;
|
|
TOnObject =function(obj:TObject):Ptruint of object;
|
|
|
|
THostIpcHandler=class
|
|
private
|
|
type
|
|
PCBNode=^TCBNode;
|
|
TCBNode=object
|
|
cb:TOnMessage;
|
|
end;
|
|
//
|
|
PCBNodeObject=^TCBNodeObject;
|
|
TCBNodeObject=object(TCBNode)
|
|
Creator:TAbstractObjectClass;
|
|
cb_obj :TOnObject;
|
|
function OnObject(mlen:DWORD;buf:Pointer):Ptruint;
|
|
end;
|
|
var
|
|
FLock :Pointer;
|
|
FMsgTable:TSTUB_HAMT32;
|
|
public
|
|
Destructor Destroy; override;
|
|
//
|
|
Procedure AddCallback(const msg:RawByteString;cb:TOnMessage);
|
|
Procedure AddCallback(const msg:RawByteString;cb:TOnObject;Creator:TAbstractObjectClass);
|
|
Procedure DelCallback(const msg:RawByteString);
|
|
Function GetCallback(mtype:DWORD):TOnMessage;
|
|
end;
|
|
|
|
THostIpcInterface=class
|
|
public
|
|
FHandler:THostIpcHandler;
|
|
Ftd :Pointer; //p_kthread
|
|
FStop :Boolean;
|
|
//
|
|
procedure error(const s:RawByteString);
|
|
procedure kevent(kev:p_kevent;count:Integer);
|
|
function OpenMainWindows():THandle;
|
|
procedure SetCaptionFps(Ffps:QWORD);
|
|
//
|
|
Function GetCallback(mtype:DWORD):TOnMessage; virtual;
|
|
function NewSyncKey:Pointer; virtual; abstract;
|
|
procedure FreeSyncKey (key:Pointer); virtual; abstract;
|
|
procedure WaitSyncKey (key:Pointer); virtual; abstract;
|
|
function GetSyncValue(key:Pointer):Ptruint; virtual; abstract;
|
|
procedure Send(mtype,mlen:DWORD;buf,key:Pointer); virtual; abstract;
|
|
procedure Update (); virtual;
|
|
//
|
|
function SendSync(mtype,mlen:DWORD;buf:Pointer):Ptruint;
|
|
procedure SendAsyn(mtype,mlen:DWORD;buf:Pointer);
|
|
function SendSync(const msg:RawByteString):Ptruint;
|
|
function SendSync(mtype:DWORD;obj:TAbstractObject):Ptruint;
|
|
procedure SendAsyn(mtype:DWORD;obj:TAbstractObject);
|
|
function SendSync(const msg:RawByteString;obj:TAbstractObject):Ptruint;
|
|
procedure SendAsyn(const msg:RawByteString;obj:TAbstractObject);
|
|
//
|
|
end;
|
|
|
|
Function HashIpcStr(const msg:RawByteString):DWORD;
|
|
|
|
//id cache
|
|
var
|
|
iERROR :DWORD=0;
|
|
iKEV_CHANGE :DWORD=0;
|
|
iKEV_EVENT :DWORD=0;
|
|
iMAIN_WINDOWS:DWORD=0;
|
|
iCAPTION_FPS :DWORD=0;
|
|
|
|
implementation
|
|
|
|
uses
|
|
kern_rwlock;
|
|
|
|
Function HashIpcStr(const msg:RawByteString):DWORD;
|
|
var
|
|
i:QWORD;
|
|
begin
|
|
i:=MurmurHash64A(@msg[1],Length(msg),$F1F0C0DE);
|
|
Result:=DWORD(i) xor DWORD(i shr 32);
|
|
end;
|
|
|
|
////
|
|
|
|
procedure _clear_hamt(data,userdata:Pointer);
|
|
begin
|
|
FreeMem(data);
|
|
end;
|
|
|
|
Destructor THostIpcHandler.Destroy;
|
|
begin
|
|
HAMT_clear32(@FMsgTable,@_clear_hamt,nil);
|
|
inherited;
|
|
end;
|
|
|
|
Procedure THostIpcHandler.AddCallback(const msg:RawByteString;cb:TOnMessage);
|
|
var
|
|
hash:DWORD;
|
|
ptr :PCBNode;
|
|
data:PPointer;
|
|
begin
|
|
hash:=HashIpcStr(msg);
|
|
Assert(hash<>iRESULT,'Hash is zero!');
|
|
|
|
ptr:=AllocMem(SizeOf(TCBNode));
|
|
ptr^.cb:=cb;
|
|
|
|
rw_wlock(FLock);
|
|
|
|
data:=HAMT_insert32(@FMsgTable,hash,ptr);
|
|
|
|
if (data<>nil) then
|
|
begin
|
|
if (data^=ptr) then
|
|
begin
|
|
//
|
|
end else
|
|
begin
|
|
Assert(False,'AddCallback');
|
|
//FreeMem(data^); //free old
|
|
//data^:=ptr; //set new
|
|
end;
|
|
end else
|
|
begin
|
|
Assert(False,'NOMEM');
|
|
end;
|
|
|
|
rw_wunlock(FLock);
|
|
end;
|
|
|
|
function THostIpcHandler.TCBNodeObject.OnObject(mlen:DWORD;buf:Pointer):Ptruint;
|
|
var
|
|
mem:TPCharStream;
|
|
obj:TAbstractObject;
|
|
begin
|
|
if (Creator=nil) or (cb_obj=nil) then
|
|
begin
|
|
Exit(Ptruint(-1));
|
|
end;
|
|
|
|
if (mlen=0) then
|
|
begin
|
|
obj:=nil;
|
|
end else
|
|
begin
|
|
mem:=TPCharStream.Create(buf,mlen);
|
|
|
|
obj:=Creator.Create;
|
|
obj.Deserialize(mem);
|
|
|
|
mem.Free;
|
|
end;
|
|
|
|
Result:=cb_obj(obj);
|
|
end;
|
|
|
|
Procedure THostIpcHandler.AddCallback(const msg:RawByteString;cb:TOnObject;Creator:TAbstractObjectClass);
|
|
var
|
|
hash:DWORD;
|
|
ptr :PCBNodeObject;
|
|
data:PPointer;
|
|
begin
|
|
hash:=HashIpcStr(msg);
|
|
Assert(hash<>iRESULT,'Hash is zero!');
|
|
|
|
ptr:=AllocMem(SizeOf(TCBNodeObject));
|
|
ptr^.cb:=@ptr^.OnObject;
|
|
ptr^.Creator:=Creator;
|
|
ptr^.cb_obj :=cb;
|
|
|
|
rw_wlock(FLock);
|
|
|
|
data:=HAMT_insert32(@FMsgTable,hash,ptr);
|
|
|
|
if (data<>nil) then
|
|
begin
|
|
if (data^=ptr) then
|
|
begin
|
|
//
|
|
end else
|
|
begin
|
|
Assert(False,'AddCallback');
|
|
//FreeMem(data^); //free old
|
|
//data^:=ptr; //set new
|
|
end;
|
|
end else
|
|
begin
|
|
Assert(False,'NOMEM');
|
|
end;
|
|
|
|
rw_wunlock(FLock);
|
|
end;
|
|
|
|
Procedure THostIpcHandler.DelCallback(const msg:RawByteString);
|
|
var
|
|
hash:DWORD;
|
|
ptr:PCBNode;
|
|
begin
|
|
hash:=HashIpcStr(msg);
|
|
Assert(hash<>iRESULT,'Hash is zero!');
|
|
|
|
rw_wlock(FLock);
|
|
|
|
ptr:=nil;
|
|
if HAMT_delete32(@FMsgTable,hash,@ptr) then
|
|
begin
|
|
FreeMem(ptr);
|
|
end;
|
|
|
|
rw_wunlock(FLock);
|
|
end;
|
|
|
|
Function THostIpcHandler.GetCallback(mtype:DWORD):TOnMessage;
|
|
var
|
|
ptr :PCBNode;
|
|
data:PPointer;
|
|
begin
|
|
Result:=nil;
|
|
|
|
rw_rlock(FLock);
|
|
|
|
data:=HAMT_search32(@FMsgTable,mtype);
|
|
if (data<>nil) then
|
|
begin
|
|
ptr:=data^;
|
|
if (ptr<>nil) then
|
|
begin
|
|
Result:=ptr^.cb;
|
|
end;
|
|
end;
|
|
|
|
rw_runlock(FLock);
|
|
end;
|
|
|
|
Function THostIpcInterface.GetCallback(mtype:DWORD):TOnMessage;
|
|
begin
|
|
Result:=nil;
|
|
if (FHandler<>nil) then
|
|
begin
|
|
Result:=FHandler.GetCallback(mtype);
|
|
end;
|
|
end;
|
|
|
|
function THostIpcInterface.SendSync(mtype,mlen:DWORD;buf:Pointer):Ptruint;
|
|
var
|
|
key:Pointer;
|
|
begin
|
|
key:=NewSyncKey;
|
|
|
|
Send(mtype,mlen,buf,key);
|
|
|
|
WaitSyncKey(key);
|
|
|
|
Result:=GetSyncValue(key);
|
|
|
|
FreeSyncKey(key);
|
|
end;
|
|
|
|
procedure THostIpcInterface.SendAsyn(mtype,mlen:DWORD;buf:Pointer);
|
|
begin
|
|
Send(mtype,mlen,buf,nil);
|
|
end;
|
|
|
|
procedure THostIpcInterface.Update();
|
|
begin
|
|
//
|
|
end;
|
|
|
|
//
|
|
|
|
function THostIpcInterface.SendSync(const msg:RawByteString):Ptruint;
|
|
begin
|
|
Result:=SendSync(HashIpcStr(msg),0,nil);
|
|
end;
|
|
|
|
function THostIpcInterface.SendSync(mtype:DWORD;obj:TAbstractObject):Ptruint;
|
|
var
|
|
key:Pointer;
|
|
mem:TMemoryStream;
|
|
begin
|
|
if (obj<>nil) then
|
|
begin
|
|
mem:=TMemoryStream.Create;
|
|
obj.Serialize(mem);
|
|
end;
|
|
|
|
key:=NewSyncKey;
|
|
|
|
if (obj<>nil) then
|
|
begin
|
|
Send(mtype,mem.Size,mem.Memory,key);
|
|
mem.Free;
|
|
end else
|
|
begin
|
|
Send(mtype,0,nil,key);
|
|
end;
|
|
|
|
WaitSyncKey(key);
|
|
|
|
Result:=GetSyncValue(key);
|
|
|
|
FreeSyncKey(key);
|
|
end;
|
|
|
|
procedure THostIpcInterface.SendAsyn(mtype:DWORD;obj:TAbstractObject);
|
|
var
|
|
mem:TMemoryStream;
|
|
begin
|
|
if (obj<>nil) then
|
|
begin
|
|
mem:=TMemoryStream.Create;
|
|
obj.Serialize(mem);
|
|
|
|
Send(mtype,mem.Size,mem.Memory,nil);
|
|
|
|
mem.Free;
|
|
end else
|
|
begin
|
|
Send(mtype,0,nil,nil);
|
|
end;
|
|
end;
|
|
|
|
function THostIpcInterface.SendSync(const msg:RawByteString;obj:TAbstractObject):Ptruint;
|
|
begin
|
|
Result:=SendSync(HashIpcStr(msg),obj);
|
|
end;
|
|
|
|
procedure THostIpcInterface.SendAsyn(const msg:RawByteString;obj:TAbstractObject);
|
|
begin
|
|
SendAsyn(HashIpcStr(msg),obj);
|
|
end;
|
|
|
|
//
|
|
|
|
procedure THostIpcInterface.error(const s:RawByteString);
|
|
begin
|
|
if (self=nil) then Exit;
|
|
if (iERROR=0) then iERROR:=HashIpcStr('ERROR');
|
|
SendSync(iERROR,Length(s)+1,pchar(s));
|
|
end;
|
|
|
|
procedure THostIpcInterface.kevent(kev:p_kevent;count:Integer);
|
|
begin
|
|
if (self=nil) then Exit;
|
|
if (iKEV_CHANGE=0) then iKEV_CHANGE:=HashIpcStr('KEV_CHANGE');
|
|
SendAsyn(iKEV_CHANGE,count*SizeOf(t_kevent),kev);
|
|
end;
|
|
|
|
function THostIpcInterface.OpenMainWindows():THandle;
|
|
begin
|
|
if (self=nil) then Exit(0);
|
|
if (iMAIN_WINDOWS=0) then iMAIN_WINDOWS:=HashIpcStr('MAIN_WINDOWS');
|
|
Result:=THandle(SendSync(iMAIN_WINDOWS,0,nil));
|
|
end;
|
|
|
|
procedure THostIpcInterface.SetCaptionFps(Ffps:QWORD);
|
|
begin
|
|
if (self=nil) then Exit;
|
|
if (iCAPTION_FPS=0) then iCAPTION_FPS:=HashIpcStr('CAPTION_FPS');
|
|
SendAsyn(iCAPTION_FPS,SizeOf(Ffps),@Ffps);
|
|
end;
|
|
|
|
|
|
end.
|
|
|