BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

TobjectList to TObjectList communication

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc
View previous topic :: View next topic  
Author Message
Donald Simmonds
Guest





PostPosted: Fri Jan 14, 2005 4:48 pm    Post subject: TobjectList to TObjectList communication Reply with quote



I am trying to work out how to communicate OOP wise with the objects in a
TObjectList and get a return.
It may be as stupidly simple as a function but I am not sure. To illustrate
I will use different Box objects.

I have a BoxA which is a List of BoxesB that it contains.
Each of those boxesB is a List of BoxesC they contain.

I want the original BoxA to receive coordinates that will select one of the
BoxesB in it's list.
Those coordinates will be passed to a final BoxC. (I can do this with simple
parameters I guess).

The final BoxC must then split itself (using the coords for size) into a
smaller BoxC and produce a new BoxC from the remainder. (This is not a
problem to implement) but... (and this is the crux)...

The BoxB must somehow receive the return of the new BoxC and the modified
BoxC and ADD the new into the BoxB List and replace the original BoxC with
the smaller version.

I am working on the principle that BoxB List should know nothing about BoxC
internals, only that it contains them and can (somehow) communicate the
instruction to Split and then get the parts Returned to the list.

Can somebody help me sort this out please?
Am I being pedantic in the isolation of the types, which while only lists,
are objects that have properties?

Thanks in anticipation
Don


Back to top
Rob Kennedy
Guest





PostPosted: Fri Jan 14, 2005 6:38 pm    Post subject: Re: TobjectList to TObjectList communication Reply with quote



Donald Simmonds wrote:
Quote:
The BoxB must somehow receive the return of the new BoxC and the modified
BoxC and ADD the new into the BoxB List and replace the original BoxC with
the smaller version.

When BoxA receives the corrdinates, it passes them to BoxB by calling a
method on BoxB. BoxB then finds the appropriate BoxC and calls a
function on that box.

function TBoxC.Split(Coordinates: TCoordinates): TBoxC;

Within that function, BoxC will create a new TBoxC instance for the
remainder, and then it will resize itself.

BoxB will receive the new BoxC instance, which it can add to its own
list. You don't need to remove anything since the old BoxC is already
the new smaller size.

Quote:
I am working on the principle that BoxB List should know nothing about BoxC
internals, only that it contains them and can (somehow) communicate the
instruction to Split and then get the parts Returned to the list.

That paragraph exactly describes what functions are for.

Quote:
Can somebody help me sort this out please?
Am I being pedantic in the isolation of the types, which while only lists,
are objects that have properties?

If you want to be pedantic, then you shouldn't be using TObjectList as
your base type. That class exposes a lot of methods, and it sounds like
you don't really want any of them to be exposed at all. Instead, declare
three new classes, TBoxA, TBoxB, and TBoxC. (One class might descend
from another, or they might all descend from a common base class, or
they might all be independent classes.)

--
Rob

Back to top
Donald Simmonds
Guest





PostPosted: Fri Jan 14, 2005 8:01 pm    Post subject: Re: TobjectList to TObjectList communication Reply with quote



Thanks for your reply Rob
In reverse order, I agree, and in fact I have copied the code from Delphi
source for TObjectlist and doctored it and included what was needed and
inherited from TList, such that only Add, Insert and Items are available and
renamed it TOList from which I then derive my ABC. In so doing I modified it
to accept only one type of object thus avoiding casting. I couldn't figure
how else to get objects with a TList.

I think you are suggesting that while I am 'in' BoxB I call a method in BoxB
(as a result of receiving coords perhaps) and that method calls a known
method of the appropriate BoxC and the return value ends up back in the
method of BoxB, where it is added to it's List.
I cannot call a method of BoxC except by running some code in BoxB, correct?
Out of interest and while I have your assistance, below is the modified
TList, which you might be good enough to peruse. I am still learning
(obviously) and may still have over done the TStrip (equivalent to BoxB),
but I need the methods listed. (I don't know why it is double spaced.
TStrip = class(TList)

private

//Strip bounds

Fleft: Integer;

Ftop: integer;

FLength: integer;

Fpitch: integer;

protected

function GetItem(Index: integer): TTrack;

procedure SetLeft(value: integer);

procedure SetTop(value: integer);

procedure SetLength(value: integer);

procedure SetPitch(value: integer);

public

constructor create(const length,pitch,top: integer);

function Add(AObject: TTrack): Integer;

procedure Insert(Index: Integer; AObject: TTrack);

property items[Index: integer]: TTrack read GetItem; default;

property Left: integer read FLeft write SetLeft;

property Top: integer read FTop write SetTop;

property Length: integer read FLength write SetLength;

property pitch: integer read Fpitch write Setpitch;

// function CutTrack(track: integer; offspring: array[;

end;


implementation

uses main;

{ TStrip }

constructor TStrip.Create(const Length,pitch,top: integer);

begin

inherited Create;

capacity:=1;

Fleft:=left;

Ftop:=top;

FLength:=Length;

Fpitch:=pitch;

add(TTrack.create(FLength,Fpitch));

end;


function TStrip.Add(AObject: TTrack): Integer;

begin

Result := inherited Add(AObject);

end;


function TStrip.GetItem(Index: integer): TTrack;

begin

result:=TTrack(inherited Items[Index]);

end;


procedure TStrip.Insert(Index: Integer; AObject: TTrack);

begin

inherited Insert(Index, AObject);

end;


procedure TStrip.SetLeft(value: integer);

begin

FLeft:=value;

end;


procedure TStrip.SetTop(value: integer);

begin

FTop:=value;

end;


procedure TStrip.SetLength(value: integer);

begin

FLength:=value;

end;


procedure TStrip.SetPitch(value: integer);

begin

FPitch:=value;

end;

Thank you

Don

"Rob Kennedy" <me3 (AT) privacy (DOT) net> wrote

Quote:
Donald Simmonds wrote:
The BoxB must somehow receive the return of the new BoxC and the
modified
BoxC and ADD the new into the BoxB List and replace the original BoxC
with
the smaller version.

When BoxA receives the corrdinates, it passes them to BoxB by calling a
method on BoxB. BoxB then finds the appropriate BoxC and calls a
function on that box.

function TBoxC.Split(Coordinates: TCoordinates): TBoxC;

Within that function, BoxC will create a new TBoxC instance for the
remainder, and then it will resize itself.

BoxB will receive the new BoxC instance, which it can add to its own
list. You don't need to remove anything since the old BoxC is already
the new smaller size.

I am working on the principle that BoxB List should know nothing about
BoxC
internals, only that it contains them and can (somehow) communicate the
instruction to Split and then get the parts Returned to the list.

That paragraph exactly describes what functions are for.

Can somebody help me sort this out please?
Am I being pedantic in the isolation of the types, which while only
lists,
are objects that have properties?

If you want to be pedantic, then you shouldn't be using TObjectList as
your base type. That class exposes a lot of methods, and it sounds like
you don't really want any of them to be exposed at all. Instead, declare
three new classes, TBoxA, TBoxB, and TBoxC. (One class might descend
from another, or they might all descend from a common base class, or
they might all be independent classes.)

--
Rob



Back to top
Rob Kennedy
Guest





PostPosted: Fri Jan 14, 2005 8:53 pm    Post subject: Re: TobjectList to TObjectList communication Reply with quote

Donald Simmonds wrote:
Quote:
In reverse order, I agree, and in fact I have copied the code from Delphi
source for TObjectlist and doctored it and included what was needed and
inherited from TList, such that only Add, Insert and Items are available and
renamed it TOList from which I then derive my ABC. In so doing I modified it
to accept only one type of object thus avoiding casting. I couldn't figure
how else to get objects with a TList.

If your class descends from TList, then it has Add, Insert, Delete,
Remove, Clear, Exchange, First, Last, Sort, and IndexOf methods, plus
whatever else I've forgotten.

Rather than inheritance, you can use composition. Make a new class that
descends directly from TObject. Call it, say, TBoxList. Internally, it
can use a TObjectList to store its items, but since TBoxList doesn't
descend from TObjectList and doesn't expose the TObjectList field
publicly, only the operations that you allow can occur.

Quote:
I think you are suggesting that while I am 'in' BoxB I call a method in BoxB
(as a result of receiving coords perhaps) and that method calls a known
method of the appropriate BoxC and the return value ends up back in the
method of BoxB, where it is added to it's List.
I cannot call a method of BoxC except by running some code in BoxB, correct?

Yes. Make BoxB the master of everything it contains. No one sees a BoxC
without going through BoxB first.

Quote:
Out of interest and while I have your assistance, below is the modified
TList, which you might be good enough to peruse. I am still learning
(obviously) and may still have over done the TStrip (equivalent to BoxB),
but I need the methods listed. (I don't know why it is double spaced.

It's probably double-spaced for the same reason nothing's indented.
Outlook Express seems to do that sometimes. Someone who actually uses OE
will have to provide more details, though; I haven't used it in at least
five years.

Quote:
constructor TStrip.Create(const Length,pitch,top: integer);
begin
inherited Create;
capacity:=1;
Fleft:=left;

You're assigning FLeft based on the Left property, which is in turn
based on the FLeft field again. That's one of the reasons for the custom
that arguments names are prefixed with the letter "A," just as fields
are prefixed with "F."

constructor TStrip.Create(const ALength, APitch, ATop, ALeft: Integer);

Quote:
Ftop:=top;
FLength:=Length;
Fpitch:=pitch;
add(TTrack.create(FLength,Fpitch));

This is probably the source of a memory leak. Who frees that object? A
TObjectList can be configured to free whatever it holds when it's
destroyed, but TList doesn't do that (because TList has no idea what
it's holding). You'll need to either override your class's destructor to
free its contents or override the Notify method the same way TObjectList
does.

Quote:
procedure TStrip.SetLength(value: integer);
begin
FLength:=value;
end;

You used FLength to initialize the first TTrack item in the list. When
you change the strip's value, are you supposed to update the lengths of
all the tracks, too? Or is TStrip.Length really more like
TStrip.DefaultLength?

--
Rob

Back to top
Donald Simmonds
Guest





PostPosted: Sat Jan 15, 2005 11:17 am    Post subject: Re: TobjectList to TObjectList communication - code.txt (0/1 Reply with quote

On Fri, 14 Jan 2005 14:53:47 -0600, Rob Kennedy <me3 (AT) privacy (DOT) net>
wrote:

Quote:
Donald Simmonds wrote:
In reverse order, I agree, and in fact I have copied the code from Delphi
source for TObjectlist and doctored it and included what was needed and
inherited from TList, such that only Add, Insert and Items are available and
renamed it TOList from which I then derive my ABC. In so doing I modified it
to accept only one type of object thus avoiding casting. I couldn't figure
how else to get objects with a TList.

Thank you Rob for your continued help.

I have attached the code I used, note that in fact I actually
descended from my modified TObjectList (TOList) as I intimated in the
first post, but posted as TList. I have not included the obvious
procedure Set... routines.
Quote:
If your class descends from TList, then it has Add, Insert, Delete,
Remove, Clear, Exchange, First, Last, Sort, and IndexOf methods, plus
whatever else I've forgotten.

I presumed that by copying the code to my unit as shown, only those

required parts are included. Am I wrong?
Quote:
Rather than inheritance, you can use composition. Make a new class that
descends directly from TObject. Call it, say, TBoxList. Internally, it
can use a TObjectList to store its items, but since TBoxList doesn't
descend from TObjectList and doesn't expose the TObjectList field
publicly, only the operations that you allow can occur.

I think you suggest that a TObjectList is introduced as a Field and

because it is Private, achieves what you said regarding exposure.
If methods etc are exposed, why does it matter if only I am calling
whatever is needed, nothing else can get called by accident?
If I do this, how do I expose the methods of TObjectList in the Public
section? is it:-
Private
FListofCBoxes.add(xxxx);
public
function FListofCBoxes.Add(AObject: TTrack): Integer;

Does this alter the calling process, which at present is items[1] to
get to a BoxC from BoxB? or is it now FListofCBoxes.items[1]?
Quote:
I think you are suggesting that while I am 'in' BoxB I call a method in BoxB
(as a result of receiving coords perhaps) and that method calls a known
method of the appropriate BoxC and the return value ends up back in the
method of BoxB, where it is added to it's List.
I cannot call a method of BoxC except by running some code in BoxB, correct?

Yes. Make BoxB the master of everything it contains. No one sees a BoxC
without going through BoxB first.

Yes understood.
Out of interest and while I have your assistance, below is the modified
TList, which you might be good enough to peruse. I am still learning
(obviously) and may still have over done the TStrip (equivalent to BoxB),
but I need the methods listed. (I don't know why it is double spaced.

See attachment for what I really did, I probably confused by not

including TOList.
Quote:
It's probably double-spaced for the same reason nothing's indented.
Outlook Express seems to do that sometimes. Someone who actually uses OE
will have to provide more details, though; I haven't used it in at least
five years.

Have just changed to Forte Agent, it seems to be better.
constructor TStrip.Create(const Length,pitch,top: integer);
begin
inherited Create;
capacity:=1;
Fleft:=left;

You're assigning FLeft based on the Left property, which is in turn
based on the FLeft field again. That's one of the reasons for the custom
that arguments names are prefixed with the letter "A," just as fields
are prefixed with "F."

I will use A in future.

The Left is in fact supposed to be the Left of BoxA which contains
this strip (BoxB), so I thought I was referring to that. Obviously
wrong and I should have passed it as a parameter. It becomes the
default left in effect, for BoxA, BoxB and; BoxC first box only. I did
not want to use a global. Is there a better way then passing a
parameter down a chain to the destination routine?
Quote:
constructor TStrip.Create(const ALength, APitch, ATop, ALeft: Integer);

Ftop:=top;
FLength:=Length;
Fpitch:=pitch;
add(TTrack.create(FLength,Fpitch));

This is probably the source of a memory leak. Who frees that object? A
TObjectList can be configured to free whatever it holds when it's
destroyed, but TList doesn't do that (because TList has no idea what
it's holding). You'll need to either override your class's destructor to
free its contents or override the Notify method the same way TObjectList
does.

The attached code shows that my new TOList is modified to permanently

set FOwnsObjects to True and I thought this would suffice to destroy.

I left the Notify code in because I don't understand it or what it
does, but presumed it to be important!!
Quote:
procedure TStrip.SetLength(value: integer);
begin
FLength:=value;
end;

You used FLength to initialize the first TTrack item in the list. When
you change the strip's value, are you supposed to update the lengths of
all the tracks, too? Or is TStrip.Length really more like
TStrip.DefaultLength?
As you say, it is a default max length, set as BoxA is created. The

BoxC items shrink and propogate but in total never must exceed this
default.

There is a lot more I could ask you, but I won't be selfish.
Thank you
Don

Back to top
Rob Kennedy
Guest





PostPosted: Sun Jan 16, 2005 1:58 am    Post subject: Re: TobjectList to TObjectList communication - code.txt (0/1 Reply with quote

Donald Simmonds wrote:
Quote:
I presumed that by copying the code to my unit as shown, only those
required parts are included. Am I wrong?

No, you're right. Your class decends from whatever you declared it to
descend from. I dislike copying code from the VCL, though, since it
smells of plagiarism or copyright infringement. I find it easier to just
create an instance of Contnrs.TObjectList when I need to store a list of
objects.

Quote:
I think you suggest that a TObjectList is introduced as a Field and
because it is Private, achieves what you said regarding exposure.

Yes. That's why I suggested it. :)

Quote:
If methods etc are exposed, why does it matter if only I am calling
whatever is needed, nothing else can get called by accident?
If I do this, how do I expose the methods of TObjectList in the Public
section? is it:-
Private
FListofCBoxes.add(xxxx);
public
function FListofCBoxes.Add(AObject: TTrack): Integer;

You declare methods of TBoxList: Add, Insert, Remove, etc. To implement
those methods, you in turn call methods on the private TObjectList instance:

type
TBoxList = class
private
FBoxes: TObjectList;
public
function Add(const ABox: TBox): Integer;
end;

function TBoxList.Add(const ABox: TBox): Integer;
begin
Result := FBoxes.Add(ABox);
end;

You won't expose the TObjectList in any way. That allows you to change
the implementation of TBoxList without having to worry about breaking
external code since you'll know that none of that code was relying on
unintended TObjectList behavior. The external code will only be using
what you explicitly made available through TBoxList.

Quote:
The Left is in fact supposed to be the Left of BoxA which contains
this strip (BoxB), so I thought I was referring to that. Obviously
wrong and I should have passed it as a parameter.

Not obviously. I'm not really sure what value "Left" refered to. (Of
course, that ambiguity is part of the problem, if not for the compiler,
then for us humans who need to read the code.)

Quote:
It becomes the
default left in effect, for BoxA, BoxB and; BoxC first box only. I did
not want to use a global. Is there a better way then passing a
parameter down a chain to the destination routine?

Pass it as a parameter to each successive routine.

--
Rob

Back to top
Donald Simmonds
Guest





PostPosted: Sun Jan 16, 2005 7:41 am    Post subject: Re: TobjectList to TObjectList communication - code.txt (0/1 Reply with quote

On Sat, 15 Jan 2005 19:58:14 -0600, Rob Kennedy <me3 (AT) privacy (DOT) net>
wrote:

Quote:
Donald Simmonds wrote:
I presumed that by copying the code to my unit as shown, only those
required parts are included. Am I wrong?

No, you're right. Your class decends from whatever you declared it to
descend from. I dislike copying code from the VCL, though, since it
smells of plagiarism or copyright infringement. I find it easier to just
create an instance of Contnrs.TObjectList when I need to store a list of
objects.

Understood. I wrongly thought the license and the provision of the

source implied that what I chose to do was acceptable.
Quote:
I think you suggest that a TObjectList is introduced as a Field and
because it is Private, achieves what you said regarding exposure.

Yes. That's why I suggested it. :)

Just clarifying that I had understood.
If methods etc are exposed, why does it matter if only I am calling
whatever is needed, nothing else can get called by accident?
If I do this, how do I expose the methods of TObjectList in the Public
section? is it:-
Private
FListofCBoxes.add(xxxx);
public
function FListofCBoxes.Add(AObject: TTrack): Integer;

You declare methods of TBoxList: Add, Insert, Remove, etc. To implement
those methods, you in turn call methods on the private TObjectList instance:

type
TBoxList = class
private
FBoxes: TObjectList;
public
function Add(const ABox: TBox): Integer;
end;

function TBoxList.Add(const ABox: TBox): Integer;
begin
Result := FBoxes.Add(ABox);
end;

This does seem a better way than mine, it is maintainable and

readable.
Quote:
You won't expose the TObjectList in any way. That allows you to change
the implementation of TBoxList without having to worry about breaking
external code since you'll know that none of that code was relying on
unintended TObjectList behavior. The external code will only be using
what you explicitly made available through TBoxList.

The above paragraph explains all
The Left is in fact supposed to be the Left of BoxA which contains
this strip (BoxB), so I thought I was referring to that. Obviously
wrong and I should have passed it as a parameter.

Not obviously. I'm not really sure what value "Left" refered to. (Of
course, that ambiguity is part of the problem, if not for the compiler,
then for us humans who need to read the code.)

It becomes the
default left in effect, for BoxA, BoxB and; BoxC first box only. I did
not want to use a global. Is there a better way then passing a
parameter down a chain to the destination routine?

Pass it as a parameter to each successive routine.
Thank you for your immensely helpful comments. I believe for now I can

move on.
I find that when reading the commonly available books, that there is
not enough of the 'rules' of coding and the properly accepted methods
of achieving something. It would be better if code done wrongly just
didn't work, then no problem, but there seems to be a multitude of
'ways of skinning a cat' that actually work but not efficiently or to
the rules.
Do you have a title for Delphi 5 that would assist?

Thanks for your help

Back to top
Bruce Roberts
Guest





PostPosted: Mon Jan 17, 2005 2:56 pm    Post subject: Re: TobjectList to TObjectList communication - code.txt (0/1 Reply with quote


"Donald Simmonds" <you (AT) don-simmonds (DOT) co.uk> wrote


Quote:
I find that when reading the commonly available books, that there is
not enough of the 'rules' of coding and the properly accepted methods
of achieving something. It would be better if code done wrongly just
didn't work, then no problem, but there seems to be a multitude of
'ways of skinning a cat' that actually work but not efficiently or to
the rules.

Efficiency is an interesting thing to measure. Sometimes one cares about
execution efficiency, sometime the concern is development time. Not often
enough of the time, IMO, the efficiency equation includes a maintenance
variable. Even if one is only concerned about execution efficiency, there
are often many sub-concerns - memory consumption, working set size, code
length. With all this complexity its difficult to arrive at hard and fast
design and coding rules, let alone ones that can be agreed upon by others.
This is not helped by the fact that most programmers operate as much on
belief as they do science.



Back to top
Marco van de Voort
Guest





PostPosted: Thu Jan 20, 2005 2:17 pm    Post subject: Re: TobjectList to TObjectList communication - code.txt (0/1 Reply with quote

On 2005-01-17, Bruce Roberts <ber (AT) bounceitattcanada (DOT) xnet> wrote:
Quote:

"Donald Simmonds" <you (AT) don-simmonds (DOT) co.uk> wrote in message
news:fm5ku0hkinhgkvbljj2cr5rh2jbamobr6d (AT) 4ax (DOT) com...

I find that when reading the commonly available books, that there is
not enough of the 'rules' of coding and the properly accepted methods
of achieving something. It would be better if code done wrongly just
didn't work, then no problem, but there seems to be a multitude of
'ways of skinning a cat' that actually work but not efficiently or to
the rules.

Efficiency is an interesting thing to measure. Sometimes one cares about
execution efficiency, sometime the concern is development time. Not often
enough of the time, IMO, the efficiency equation includes a maintenance
variable. Even if one is only concerned about execution efficiency, there
are often many sub-concerns - memory consumption, working set size, code
length.

Moreover the possibilities to extend the program (both as in "doable", and
with decent performance), use beyond initial parameters (typical example:
data amount increases magnitude beyond expectation.)

A program that is designed to just run on current hardware, can be stressed too far by
larger (production) datasets, or by the extra processing or footprint needed by a
relatively simple extension.

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.