mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-13 22:39:21 +02:00
rtl: added rtti.pas with TVirtualInterface
This commit is contained in:
parent
691d3d8bdc
commit
30fed36605
@ -32,7 +32,7 @@
|
||||
<Description Value="pas2js RTL - Run Time Library"/>
|
||||
<License Value="Modified LGPL2 as the FPC packages."/>
|
||||
<Version Major="1"/>
|
||||
<Files Count="19">
|
||||
<Files Count="20">
|
||||
<Item1>
|
||||
<HasRegisterProc Value="True"/>
|
||||
</Item1>
|
||||
@ -109,6 +109,10 @@
|
||||
<Filename Value="webrouter.pp"/>
|
||||
<UnitName Value="webrouter"/>
|
||||
</Item19>
|
||||
<Item20>
|
||||
<Filename Value="rtti.pas"/>
|
||||
<UnitName Value="RTTI"/>
|
||||
</Item20>
|
||||
</Files>
|
||||
<UsageOptions>
|
||||
<CustomOptions Value="-dPas2js"/>
|
||||
|
107
packages/rtl/rtti.pas
Normal file
107
packages/rtl/rtti.pas
Normal file
@ -0,0 +1,107 @@
|
||||
{
|
||||
This file is part of the Pas2JS run time library.
|
||||
Copyright (c) 2018 by Mattias Gaertner
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
unit RTTI;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, Types, TypInfo;
|
||||
|
||||
type
|
||||
TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
|
||||
const Args: TJSValueDynArray): JSValue of object;
|
||||
|
||||
{ TVirtualInterface: A class that can implement any IInterface. Any method
|
||||
call is handled by the OnInvoke event. }
|
||||
TVirtualInterface = class(TInterfacedObject, IInterface)
|
||||
private
|
||||
FOnInvoke: TVirtualInterfaceInvokeEvent;
|
||||
public
|
||||
constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
|
||||
constructor Create(InterfaceTypeInfo: Pointer;
|
||||
const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
|
||||
property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
|
||||
end;
|
||||
|
||||
procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
|
||||
const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
|
||||
|
||||
implementation
|
||||
|
||||
procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
|
||||
const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
|
||||
asm
|
||||
var IntfType = InterfaceTypeInfo.interface;
|
||||
var i = Object.create(IntfType);
|
||||
var o = { $name: "virtual", $fullname: "virtual" };
|
||||
i.$o = o;
|
||||
do {
|
||||
var names = IntfType.$names;
|
||||
if (!names) break;
|
||||
for (var j=0; j<names.length; j++){
|
||||
let fnname = names[j];
|
||||
i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
|
||||
}
|
||||
IntfType = Object.getPrototypeOf(IntfType);
|
||||
} while(IntfType!=null);
|
||||
IntfVar.set(i);
|
||||
end;
|
||||
|
||||
{ TVirtualInterface }
|
||||
|
||||
constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
|
||||
asm
|
||||
var IntfType = InterfaceTypeInfo.interface;
|
||||
if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
|
||||
var guid = IntfType.$guid;
|
||||
var i = Object.create(IntfType); // needed by IntfVar is IntfType
|
||||
i.$o = this;
|
||||
// copy IInterface methods: _AddRef, _Release, QueryInterface
|
||||
var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
|
||||
var map = this.$intfmaps[iinterfaceguid];
|
||||
for (var key in map){
|
||||
var v = map[key];
|
||||
if (typeof(v)!=='function') continue;
|
||||
i[key] = map[key];
|
||||
}
|
||||
// all other methods call OnInvoke
|
||||
do {
|
||||
var names = IntfType.$names;
|
||||
if (!names) break;
|
||||
for (var j=0; j<names.length; j++){
|
||||
let fnname = names[j];
|
||||
if (i[fnname]) continue;
|
||||
i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
|
||||
}
|
||||
IntfType = Object.getPrototypeOf(IntfType);
|
||||
} while(IntfType!=null);
|
||||
// create a new list of interface map, supporting IInterface and IntfType
|
||||
this.$intfmaps = {};
|
||||
this.$intfmaps[iinterfaceguid] = map;
|
||||
this.$intfmaps[guid] = {};
|
||||
// store the implementation of IntfType (used by the as-operator)
|
||||
this.$interfaces = {};
|
||||
this.$interfaces[guid] = i;
|
||||
end;
|
||||
|
||||
constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
|
||||
const InvokeEvent: TVirtualInterfaceInvokeEvent);
|
||||
begin
|
||||
Create(InterfaceTypeInfo);
|
||||
OnInvoke:=InvokeEvent;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user