[fpc-pascal]TCollection question
Is there an example of using TCollection or something (without having to write the code myself) that manages a collection of FPC style classes (objects) ? I'd like to see one, code I have written to handle a dynamic array of objects has gone out of control... (Using FPC classes here) cheers James -- - - James Mills Zero Defect Software Engineers Group - ZDSEG ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
> Is there an example of using TCollection or something (without having to > write the code myself) that manages a collection of FPC style classes > (objects) ? > > I'd like to see one, code I have written to handle a dynamic array of > objects has gone out of control... (Using FPC classes here) IIRC, TCollection only stores TCollectionItem derived classes. TList is closer to what you want probably. ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
On Sun, Jul 06, 2003 at 04:25:15PM +0200, Marco van de Voort wrote: > > Is there an example of using TCollection or something (without having to > > write the code myself) that manages a collection of FPC style classes > > (objects) ? > > > > I'd like to see one, code I have written to handle a dynamic array of > > objects has gone out of control... (Using FPC classes here) > > IIRC, TCollection only stores TCollectionItem derived classes. > > TList is closer to what you want probably. Is there an example other than list.pp in the fcl source ? Also just for the record of knowing... I have attached datanicks.pas which hold a dynamic array of TNick ... Is this what TList already does (if so I'm wasting my time writing my own code...) ? cheers James > > ___ > fpc-pascal maillist - [EMAIL PROTECTED] > http://lists.freepascal.org/mailman/listinfo/fpc-pascal -- - - James Mills Zero Defect Software Engineers Group - ZDSEG unit dataNicks; interface uses sysUtils, Functions, tokenizerClass, nickClass; var nicks: PNick; nNicks: Integer; procedure init; procedure done; procedure addNick(data: String); procedure addNick(data: String; index: Integer); function backupNick(nick: String): TNick; procedure copyNickData(srcNick: TNick; destNick: TNick); function getNick(nick: String): Integer; procedure delNick(nick: String); function isIdentified(nick: String): Boolean; function isIdentified(nick: String; otherNick: String): Boolean; implementation procedure init; begin nNicks := 0; getMem(nicks, sizeOf(TNick) * nNicks); end; procedure done; var I: Integer; begin for I := 0 to (nNicks - 1) do begin nicks[I].free; end; freeMem(nicks); end; procedure addNick(data: String); var tokens: TTokenizer; nick: String; hops: Integer; signon: longInt; ident: String; host: String; server: String; unused: String; name: String; begin tokens := TTokenizer.Create(data); nick := tokens.nextToken; hops := strToInt(tokens.nextToken); signon := strToInt(tokens.nextToken); ident := tokens.nextToken; host := tokens.nextToken; server := tokens.nextToken; unused := tokens.nextToken; name := strip(tokens.restOfTokens); tokens.free; inc(nNicks); reAllocMem(nicks, sizeOf(TNick) * nNicks); nicks[(nNicks - 1)] := TNick.Create(nick, hops, signon, ident, host, server, unused, name); end; procedure addNick(data: String; index: Integer); var tokens: TTokenizer; nick: String; hops: Integer; signon: longInt; ident: String; host: String; server: String; unused: String; name: String; tmpNick: TNick; I: Integer; begin tokens := TTokenizer.Create(data); nick := tokens.nextToken; hops := strToInt(tokens.nextToken); signon := strToInt(tokens.nextToken); ident := tokens.nextToken; host := tokens.nextToken; server := tokens.nextToken; unused := tokens.nextToken; name := strip(tokens.restOfTokens); tokens.free; if index < nNicks then begin tmpNick := backupNick(nick); nicks[index].free; nicks[index] := TNick.Create(nick, hops, signon, ident, host, server, unused, name); copyNickData(tmpNick, nicks[index]); tmpNick.free; end; end; function backupNick(nick: String): TNick; var data: String; tokens: TTokenizer; hops: Integer; signon: longInt; ident: String; host: String; server: String; unused: String; name: String; index: Integer; I: Integer; tmpNick: TNick; begin index := getNick(nick); if index > -1 then begin data := nicks[index].getData; tokens := TTokenizer.Create(data); tokens.nextToken; hops := strToInt(tokens.nextToken); signon := strToInt(tokens.nextToken); ident := tokens.nextToken; host := tokens.nextToken; server := tokens.nextToken; unused := tokens.nextToken; name := strip(tokens.restOfTokens); tokens.free; tmpNick := TNick.Create(nick, hops, signon, ident, host, server, unused, name); for I := 0 to (nicks[index].numAccess - 1) do begin tmpNick.addAccess(nicks[index].getAccess(I)); end; tmpNick.addMode(nicks[index].getModes); for I := 0 to (nicks[index].numChannels - 1) do begin tmpNick.addChannel(nicks[index].getChannel(I)); end; tmpNick.setUseMsg(nicks[index].getUseMsg); tmpNick.setAutoAdd(nicks[index].getAutoAdd); backupNick := tmpNick; end else begin backupNick := nil; end; end; procedure copyNickData(srcNick: TNick; destNick: TNick); var I: Integer; begin for I := 0 to (srcNick.numAccess - 1) do begin destNick.addAccess(srcNick.getAccess(I)); end; for I := 0 to (srcNick.numChannels - 1) do begin destNick.addChannel(srcNick.getChannel(I)); end; destNick.addMode(srcNick.getModes); destNick.setUseMsg(srcNick.getUseMsg); destNick.setAutoAdd(srcNick.getAutoAdd); end; function getNick(nick: String): Integer; var I: Integer; index: Integer; begin index := -1; for I := 0 to (nNicks - 1) do begin if upperCase(nicks[I].getNick) = upperCase(nick) then
Re: [fpc-pascal]TCollection question
> > IIRC, TCollection only stores TCollectionItem derived classes. > > > > TList is closer to what you want probably. > > Is there an example other than list.pp in the fcl source ? > > Also just for the record of knowing... I have attached datanicks.pas > which hold a dynamic array of TNick ... Is this what TList already does > (if so I'm wasting my time writing my own code...) ? Pretty much yes, but in a class wrapper. You can add and remove items, iterate through them etc. Maybe you can derive a class from TList to customize it a bit. There are two things to think of: - you yourself have to make sure that elements are properly freed, so when deleting object A, get a reference to it, delete it from the list, and then free the object. (however that can be automized in the class warpper) - The internal list has two counters, instead of just "nNicks". One (capacity) is the reserved space, the other (count) is the amount of elements filled. This avoids too many memory fragmenting reallocs. (but that's better, not worse) I learned to use the classes from code snippets written for Delphi. There is FCL documentation somewhere (and it will be in the next full release), but I couldn't find a recent version so fast. So I put down a very old version (April 2002) on the web here: www.stack.nl/~marcov/fcl.pdf it at least describes the tlist methods. ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
On Sun, Jul 06, 2003 at 05:11:17PM +0200, Marco van de Voort wrote: > > > IIRC, TCollection only stores TCollectionItem derived classes. > > > > > > TList is closer to what you want probably. > > > > Is there an example other than list.pp in the fcl source ? > > > > Also just for the record of knowing... I have attached datanicks.pas > > which hold a dynamic array of TNick ... Is this what TList already does > > (if so I'm wasting my time writing my own code...) ? > > Pretty much yes, but in a class wrapper. You can add and remove items, > iterate through them etc. Maybe you can derive a class from TList to > customize it a bit. However TList by itself would work though ? > > There are two things to think of: > - you yourself have to make sure that elements are properly freed, so >when deleting object A, get a reference to it, delete it from the list, >and then free the object. (however that can be automized in the class >warpper) Is this all done and automated in TList ? > - The internal list has two counters, instead of just "nNicks". One >(capacity) is the reserved space, the other (count) is the amount of >elements filled. This avoids too many memory fragmenting reallocs. > (but that's better, not worse) > > I learned to use the classes from code snippets written for Delphi. > > There is FCL documentation somewhere (and it will be in the next full > release), but I couldn't find a recent version so fast. > > So I put down a very old version (April 2002) on the web here: > > www.stack.nl/~marcov/fcl.pdf I think it's here also in html format: http://www.nl.freepascal.org/docs-html/fcl/classes/tlist.html cheers James > > it at least describes the tlist methods. > > ___ > fpc-pascal maillist - [EMAIL PROTECTED] > http://lists.freepascal.org/mailman/listinfo/fpc-pascal -- - - James Mills Zero Defect Software Engineers Group - ZDSEG ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
> On Sun, Jul 06, 2003 at 05:11:17PM +0200, Marco van de Voort wrote: > > > which hold a dynamic array of TNick ... Is this what TList already does > > > (if so I'm wasting my time writing my own code...) ? > > > > Pretty much yes, but in a class wrapper. You can add and remove items, > > iterate through them etc. Maybe you can derive a class from TList to > > customize it a bit. > > However TList by itself would work though ? Basically yes. But derive it anyway, in case you want to extend it later. > > - you yourself have to make sure that elements are properly freed, so > >when deleting object A, get a reference to it, delete it from the list, > >and then free the object. (however that can be automized in the class > >warpper) > Is this all done and automated in TList ? No. So you have to that yourself. This because TList can also store pointers to records, which don't have to be finalised. So deallocation is still manual. But it is trivial. Assume you want to delete entry 3, assuming that variable TheList is the TList: var t : MyObjectType t:=MyObjectType(TheList[3]); TheList.delete(3); t.free; You can solve it like this: (untested) type tmyTList = class TList public procedure DeleteCompletely(index :Integer); end; procedure tmyTList.DeleteCompletely(index: Integer); var t : MyObjecType; begin t:=MyObjectType(Items[3]); delete(3); if t<>NIL t.free; end; See TList as a versatile baseclass to quickly build a dedicated, very easy to use container on top of. > > There is FCL documentation somewhere (and it will be in the next full > > release), but I couldn't find a recent version so fast. > > > > So I put down a very old version (April 2002) on the web here: > > > > www.stack.nl/~marcov/fcl.pdf > > I think it's here also in html format: > http://www.nl.freepascal.org/docs-html/fcl/classes/tlist.html That's the place I meant yes. ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
On Sun, Jul 06, 2003 at 05:31:59PM +0200, Marco van de Voort wrote: > > On Sun, Jul 06, 2003 at 05:11:17PM +0200, Marco van de Voort wrote: > > > > which hold a dynamic array of TNick ... Is this what TList already does > > > > (if so I'm wasting my time writing my own code...) ? > > > > > > Pretty much yes, but in a class wrapper. You can add and remove items, > > > iterate through them etc. Maybe you can derive a class from TList to > > > customize it a bit. > > > > However TList by itself would work though ? > > Basically yes. But derive it anyway, in case you want to extend it later. In this case then as I've both read your replies and the webpage about TList I shall extend it :) That'll probably be the best option. Right ? Thanks for your prompt help, I dunno why I'm coding at 0140 in the bloody morning but anyway :) cheers James > > > > - you yourself have to make sure that elements are properly freed, so > > >when deleting object A, get a reference to it, delete it from the list, > > >and then free the object. (however that can be automized in the class > > >warpper) > > Is this all done and automated in TList ? > > No. So you have to that yourself. This because TList can also store pointers > to records, which don't have to be finalised. So deallocation is still > manual. > > But it is trivial. Assume you want to delete entry 3, assuming that variable > TheList is the TList: > > var t : MyObjectType > > t:=MyObjectType(TheList[3]); > TheList.delete(3); > t.free; > > You can solve it like this: (untested) > > type tmyTList = class TList > public > procedure DeleteCompletely(index :Integer); > end; > > procedure tmyTList.DeleteCompletely(index: Integer); > > var t : MyObjecType; > > begin > t:=MyObjectType(Items[3]); > delete(3); > if t<>NIL >t.free; > end; > > See TList as a versatile baseclass to quickly build a dedicated, very > easy to use container on top of. > > > > There is FCL documentation somewhere (and it will be in the next full > > > release), but I couldn't find a recent version so fast. > > > > > > So I put down a very old version (April 2002) on the web here: > > > > > > www.stack.nl/~marcov/fcl.pdf > > > > I think it's here also in html format: > > http://www.nl.freepascal.org/docs-html/fcl/classes/tlist.html > > That's the place I meant yes. > > ___ > fpc-pascal maillist - [EMAIL PROTECTED] > http://lists.freepascal.org/mailman/listinfo/fpc-pascal -- - - James Mills Zero Defect Software Engineers Group - ZDSEG ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
Actually Michael, Could you possibly spare 5 mins and give a really simple example of a TList descandent ? I'm a tad confused here, (too slowly getting anywhere)... Thank you :) cheers James ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It will do a lot more for you. It can 'own' the objects, and therefore free you from needing to manage them. Simple descendent (typed at speed, with no testing): N.B. This is a WRAPPER because it allows the programmer more control over the interface to the class. However a descendent would work the same way pretty much. You'd probably just alter the 'Add' to 'AddXXX' so as to not clash with 'Add' from TList. Otherwise you would hide the method and make in unavailable. This wrapper is really usefull... I use this basic design all the time!! TMyListItemClass = class; {your class to store} TMyList = class private FList: TList; protected procedure SetItem( Index: integer; Value: TMyListItemClass); function GetItem(Index: integer): TMyListItemClass; public Constructor Create; virtual; Destructor Destroy; override; function Add(AItem: TMyListItemClass): integer; procedure Delete( AIndex: integer ); function Count: integer; property Items[Index: integer]: TMyListItemClass read GetItem write SetItem; end; procedure SetItem( Index: integer; Value: TMyListItemClass); begin FList[Index] := Value; end; function GetItem(Index: integer): TMyListItemClass; begin Result := TMyListItemClass(FList[Index] ); end; Constructor Create; virtual; begin FList := TList.Create; end; Destructor Destroy; override; begin {don't forget some code to empty list} FList.Free; inherited; end; function Add(AItem: TMyListItemClass): integer; begin result := FList.Add(AItem); end; procedure Delete( AIndex: integer ); begin FList.Delete(AIndex); end; function Count: integer; begin Result := FList.Count; end; - Original Message - From: "James Mills" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Sunday, July 06, 2003 4:56 PM Subject: Re: [fpc-pascal]TCollection question > Actually Michael, > > Could you possibly spare 5 mins and give a really simple example of a > TList descandent ? I'm a tad confused here, (too slowly getting > anywhere)... > > Thank you :) > > cheers > James > > ___ > fpc-pascal maillist - [EMAIL PROTECTED] > http://lists.freepascal.org/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
On Sun, Jul 06, 2003 at 10:38:28PM +0100, Matt and Lisa Emson wrote: > Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It > will do a lot more for you. It can 'own' the objects, and therefore free you > from needing to manage them. > > Simple descendent (typed at speed, with no testing): > > N.B. This is a WRAPPER because it allows the programmer more control over > the interface to the class. However a descendent would work the same way > pretty much. You'd probably just alter the 'Add' to 'AddXXX' so as to not > clash with 'Add' from TList. Otherwise you would hide the method and make in > unavailable. This wrapper is really usefull... I use this basic design all > the time!! Thank you for this. I was a tad confused as my original idea was wrong in that I tried to create a pure descandent of TList and extend it... I will use your basic design below, thank you :) cheers James > > TMyListItemClass = class; {your class to store} > > TMyList = class > private > FList: TList; > protected > procedure SetItem( Index: integer; Value: TMyListItemClass); > function GetItem(Index: integer): TMyListItemClass; > public > Constructor Create; virtual; > Destructor Destroy; override; > > function Add(AItem: TMyListItemClass): integer; > procedure Delete( AIndex: integer ); > function Count: integer; > > property Items[Index: integer]: TMyListItemClass read GetItem write > SetItem; > end; > > procedure SetItem( Index: integer; Value: TMyListItemClass); > begin > FList[Index] := Value; > end; > > function GetItem(Index: integer): TMyListItemClass; > begin > Result := TMyListItemClass(FList[Index] ); > end; > > Constructor Create; virtual; > begin > FList := TList.Create; > end; > > Destructor Destroy; override; > begin > {don't forget some code to empty list} > FList.Free; > > inherited; > end; > > function Add(AItem: TMyListItemClass): integer; > begin > result := FList.Add(AItem); > end; > > procedure Delete( AIndex: integer ); > begin > FList.Delete(AIndex); > end; > > function Count: integer; > begin > Result := FList.Count; > end; > > > - Original Message - > From: "James Mills" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Sunday, July 06, 2003 4:56 PM > Subject: Re: [fpc-pascal]TCollection question > > > > Actually Michael, > > > > Could you possibly spare 5 mins and give a really simple example of a > > TList descandent ? I'm a tad confused here, (too slowly getting > > anywhere)... > > > > Thank you :) > > > > cheers > > James > > > > ___ > > fpc-pascal maillist - [EMAIL PROTECTED] > > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > > ___ > fpc-pascal maillist - [EMAIL PROTECTED] > http://lists.freepascal.org/mailman/listinfo/fpc-pascal -- - - James Mills Zero Defect Software Engineers Group - ZDSEG ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal]TCollection question
On Sun, Jul 06, 2003 at 10:38:28PM +0100, Matt and Lisa Emson wrote: > Why not use a TObjectList?? IIRC that is available. In unit Contnrs.pas. It > will do a lot more for you. It can 'own' the objects, and therefore free you > from needing to manage them. > > Simple descendent (typed at speed, with no testing): > > N.B. This is a WRAPPER because it allows the programmer more control over > the interface to the class. However a descendent would work the same way > pretty much. You'd probably just alter the 'Add' to 'AddXXX' so as to not > clash with 'Add' from TList. Otherwise you would hide the method and make in > unavailable. This wrapper is really usefull... I use this basic design all > the time!! A question about your basic-design and using TList (and descandents in general)... Could I not do this: TMyList = class(TList); . . . And thereby extend the basic TList class into a custom List ? The way you use TList is as a private variable in a generic class. cheers James > > TMyListItemClass = class; {your class to store} > > TMyList = class > private > FList: TList; > protected > procedure SetItem( Index: integer; Value: TMyListItemClass); > function GetItem(Index: integer): TMyListItemClass; > public > Constructor Create; virtual; > Destructor Destroy; override; > > function Add(AItem: TMyListItemClass): integer; > procedure Delete( AIndex: integer ); > function Count: integer; > > property Items[Index: integer]: TMyListItemClass read GetItem write > SetItem; > end; > > procedure SetItem( Index: integer; Value: TMyListItemClass); > begin > FList[Index] := Value; > end; > > function GetItem(Index: integer): TMyListItemClass; > begin > Result := TMyListItemClass(FList[Index] ); > end; > > Constructor Create; virtual; > begin > FList := TList.Create; > end; > > Destructor Destroy; override; > begin > {don't forget some code to empty list} > FList.Free; > > inherited; > end; > > function Add(AItem: TMyListItemClass): integer; > begin > result := FList.Add(AItem); > end; > > procedure Delete( AIndex: integer ); > begin > FList.Delete(AIndex); > end; > > function Count: integer; > begin > Result := FList.Count; > end; > > > - Original Message - > From: "James Mills" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Sunday, July 06, 2003 4:56 PM > Subject: Re: [fpc-pascal]TCollection question > > > > Actually Michael, > > > > Could you possibly spare 5 mins and give a really simple example of a > > TList descandent ? I'm a tad confused here, (too slowly getting > > anywhere)... > > > > Thank you :) > > > > cheers > > James > > > > ___ > > fpc-pascal maillist - [EMAIL PROTECTED] > > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > > ___ > fpc-pascal maillist - [EMAIL PROTECTED] > http://lists.freepascal.org/mailman/listinfo/fpc-pascal -- - - James Mills Zero Defect Software Engineers Group - ZDSEG ___ fpc-pascal maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-pascal