Solved

TBucketList Example Delphi

Posted on 2013-01-31
5
1,430 Views
Last Modified: 2013-02-14
Is there anyone that can give me a complete example on how to use TBucketList? I am particularly interested in how functions can be stored in the Bucketlist and then executed like a branch vector table. I am using Delphi 7, 2010, XE2, XE3.
0
Comment
Question by:davinci1942
  • 3
  • 2
5 Comments
 
LVL 7

Expert Comment

by:Beneford
ID: 38840909
Storing functions is a bit tricky, but can be done.
I use this technique infrequently, but normally using TStringList rather than TBucketList - using a string as the key and the Object for storing the data.

Am I right in thinking you want a procedure (or function) of an object (as opposed to a procedure/function outside an object?
The issue is that a procedure pointer is 8 bytes, but a pointer (as stored by the TBucketList or TList) is only 4 bytes.

A procedure outside an object is 4 bytes, and this can also be stored in a bucket list - see below.

An example:
You have some objects of class TMyClass with procedures P1, P2, P3.
You have multiple objects of TMyClass, and you want the BucketList to hold one of the functions for each object.

To do this, define a new class:
 
  TObjProc=procedure(Sender:TObject) of object;
  TCallMe = class(TObject)
   private
     p:TObjProc;
   public
     constructor create(ap:TObjProc);
     procedure call(param:TObject);
  end;

procedure TCallMe.call(Param:TObject<wbr ></wbr>);
begin
     p(Param);
end;

constructor TCallMe.create(ap: TObjProc);
begin
     inherited Create;
     p:=ap;
end;

Open in new window


Then you load the BucketList with
bl.Add(anInstanceOfMyClass,TCallMe.create(anInstanceOfMyClass.P1));

Then you can call the procedure using:
TCallMe(bl.Data[anInstanceOfMyClass]).p(param);

There's no need for the key (first parameter to Add, parameter of Data) to be the same object has the procedure that is called.

Of course, you should update the definition of TObjProc to be whatever you need it to be. You will need to have appropriate compatibility with parameters in the definition and the parameters used on the call.
Don't forget to free the objects before they are removed from the BucketList...


If you really want a procedure that is not an object, then you can:
bl.add(anObject,@aprocedure)

and then call it using:
type TProc=procedure; // Define this in the interface section with your other types.
TProc(bl[anObject]);

(define TProc with the appropriate parameters if you need them.)
0
 

Author Comment

by:davinci1942
ID: 38861110
I am still not clear .. could I get a working example, say 3 items in the list, 3 different functions will be called by each of the entries passing different parameters?
0
 
LVL 7

Expert Comment

by:Beneford
ID: 38863039
Try the attached.

The TBucketList is quite a structure if all you want is to call functions on a list of objects.
I would normally use TList and store the TCallMe objects in it (you can always add housekeeping information to the TCallMe class to help manage them).
TestMain.pas
TestMain.dfm
0
 

Author Comment

by:davinci1942
ID: 38870060
If this is overkill, how would I use a Tlist as you refer to. Can you give me an example?

Maybe it would help if I explain what I am trying to use it for.
I have a large table which consists of the following fields for each element::
A code, a flag a procedure that needs to be called and a result. It would look something like:

Code: string;
Flag: string;
Function: Procedure Call;
Result: string;

This table has many elements.

Rather than if else or case it to death, I want to get it more organized and easy to maintain.  The TBucketList looked like it might be the answer. If you have a better solution, I would be very interested in seeing how this could be approached.
0
 
LVL 7

Accepted Solution

by:
Beneford earned 500 total points
ID: 38870761
Have you tried adapting my last answer to your requirements?
TBucketList has the foreach method, which TList doesn't, but it's easy to to a loop over all the elements...

On the other hand, it could be that your best solution is through a class hierarchy. Have a look at http://delphi.about.com/od/oopindelphi/a/delphi_oop12_3.htm and see if that gives some clues.

Can you give a more specific example of how th procedure is called (you call it a procedure, which implies it isn't a function, but you have a result field. What is 'result' used for?
Does the procedure have parameters? If so, are they always the same?
0

Featured Post

Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

Join & Write a Comment

This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
This is about my first experience with programming Arduino.
This video shows how use content aware, what it’s used for, and when to use it over other tools.
The viewer will learn how to successfully download and install the SARDU utility on Windows 8, without downloading adware.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now