Re: [fpc-pascal]TCollection question

2003-07-06 Thread James Mills
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
begin
	index := 

Re: [fpc-pascal]TCollection question

2003-07-06 Thread Marco van de Voort
  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

2003-07-06 Thread Marco van de Voort
 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 tNIL
   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

2003-07-06 Thread James Mills
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 tNIL
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

2003-07-06 Thread James Mills
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

2003-07-06 Thread Matt and Lisa Emson
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

2003-07-06 Thread James Mills
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