View Full Version : How to make a list of Method pointers?
chronozphere
26-04-2010, 02:42 PM
Hey guys
For my current project, I need to be able to make a list of method pointers.
Lets say I have these method types
{:: TnaEventHookProc ::}
TnaEventHookFunc = function (aEvent: Pointer): Boolean of object;
PnaEventHookFunc = ^TnaEventHookFunc;
{:: TnaUpdateProc ::}
TnaUpdateProc = procedure of object;
PnaUpdateProc = ^TnaUpdateProc;
I want to be able to store methods of these types on lists and call them all at once with the same paramters. Because these are methods (and not just functions/procedures) the variables are not just pointers. The are infact 8 bytes (contain a pointer to the procedure and one to the "Self" object).
Can anyone think of a way to make a list datastructure for this? I'm not very good with method-vars.
Thanks in advance. :)
Andreaz
26-04-2010, 02:54 PM
This is how i've done it
PMethodList = ^TMethodList;
TMethodList = Array[0..$00FFFFFF] of TMethod;
// TPHXMethodList
//------------------------------------------------------------------------------
TPHXMethodList = class
private
FCount : Integer;
FCapacity: Integer;
FList: PMethodList;
Procedure Grow;
procedure SetCapacity(const Value: Integer);
procedure SetCount (const Value: Integer);
function GetItem(Index: integer): TMethod;
procedure SetItem(Index: Integer; const AValue: TMethod);
public
constructor Create;
destructor Destroy; override;
Procedure Clear;
// Add a method to the list
procedure Add(const AMethod: TMethod);
// Remove a method from the list
procedure Remove(const AMethod: TMethod);
// Returns the index of a method in the list, -1 if not found
Function IndexOf(const AMethod: TMethod): Integer;
// Number of items in the list
Property Count : Integer read FCount write SetCount;
// The capacity of the list
Property Capacity: Integer read FCapacity write SetCapacity;
// The internal list
Property List: PMethodList read FList;
// Gets and sets items in the list
Property Items[Index: Integer]: TMethod read GetItem write SetItem; default;
end;
chronozphere
26-04-2010, 03:20 PM
Huh? Never seen such a List class. Why don't you use a dynamic array? :)
Could you show me the source of some of the methods of this class?
I'd be interested in SetCapacity, Add, IndexOf etc..
Thanks. :)
JSoftware
26-04-2010, 05:19 PM
type
TMethodList = specialize TFPGList<TMethod>;
;D
Andreaz
27-04-2010, 03:21 PM
Huh? Never seen such a List class. Why don't you use a dynamic array? :)
Could you show me the source of some of the methods of this class?
I'd be interested in SetCapacity, Add, IndexOf etc..
Thanks. :)
The implementation is basically the same as the Classes.TList implementation, just changed from Pointer to TMethod as data carrier.
Anyhow this is how it looks
constructor TPHXMethodList.Create;
begin
end;
destructor TPHXMethodList.Destroy;
begin
SetCapacity(0);
inherited Destroy;
end;
procedure TPHXMethodList.Grow;
var Delta: Integer;
begin
if FCapacity > 64 then
Delta := FCapacity div 4
else
if FCapacity > 8 then
Delta := 16
else
Delta := 4;
SetCapacity(Count + Delta);
end;
procedure TPHXMethodList.SetCapacity(const Value: Integer);
begin
if FCapacity <> Value then
begin
FCapacity := Value;
ReallocMem(FList, FCapacity * SizeOf(TMethod));
end;
end;
procedure TPHXMethodList.SetCount(const Value: Integer);
begin
FCount := Value;
if(FCount > FCapacity) then Grow;
end;
procedure TPHXMethodList.Clear;
begin
FCount:= 0;
end;
procedure TPHXMethodList.Add(const AMethod: TMethod);
begin
SetCount(Count + 1);
FList^[Count - 1].Data:= AMethod.Data;
FList^[Count - 1].Code:= AMethod.Code;
end;
procedure TPHXMethodList.Remove(const AMethod: TMethod);
var Index: integer;
begin
Index:= IndexOf(AMethod);
// The method isnt found, dont do anything more
if Index < 0 then Exit;
if Index < Count then
begin
System.Move(FList^[Index + 1], FList^[Index], (FCount - Index) * SizeOf(TMethod));
end;
Dec(FCount);
end;
function TPHXMethodList.IndexOf(const AMethod: TMethod): Integer;
var Index: integer;
begin
For Index:=0 to Count-1 do
begin
if (FList^[Index].Data = AMethod.Data) and (FList^[Index].Code = AMethod.Code) then
begin
Result:= Index;
Exit;
end;
end;
Result:= -1;
end;
function TPHXMethodList.GetItem(Index: integer): TMethod;
begin
Result:= FList^[Index];
end;
procedure TPHXMethodList.SetItem(Index: Integer; const AValue: TMethod);
begin
FList^[Index]:= AValue;
end;
chronozphere
27-04-2010, 05:11 PM
Thanks a bunch mate! :)
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.