[Gambas-user] gb3 RC1: using structures to replace the loss of Mk$ functions

Benoît Minisini gambas at ...1...
Sun Apr 3 09:11:00 CEST 2011


> On 04/01/2011 05:24 AM, Benoît Minisini wrote:
> > Using a structure just allow you to directly use the READ/WRITE
> > instruction because they have a build-in serialization support. But as
> > you noticed, handling a lot of different structures is not handy!
> 
> Yes, because I need to keep a transaction history of all the structures
> but there's no easy way to store different structures en masse.
> 
> > Hopefully, you don't have to use structures. You can create one class for
> > each packet type, and let them inherit the same parent class. Each class
> > will have its own write method (and read) that will
> > serialize/unserialize the packet to/from a given stream (that should be
> > a Socket).
> 
> This sounds good, but I'm a guy whose programming skills evolved from a
> BASIC dialect in GEM on an Amstrad PC-1512 to GW-BASIC, QBasic,
> QuickBASIC 4.5, VB 6 and now GAMBAS. While some build simple projects
> using advanced tools, I build advanced projects using simple tools (not
> that gb is simple!). Inheritance, classes and objects are a little alien
> to me despite reading the documentation. If anyone has an explanation of
> these things that even a newbie could understand, I'd be grateful.
> 

Here is an explanation, but not a real example :

1) You define a class named "Packet", that will be the parent class of all 
real packet classes. That class has an ID field, and three methods: Send, 
Receive, and _Receive (with an underscore before).

The Receive methods is static. That means it is a normal procedure. Receive 
will call _Receive to do the real job.

Send and _Receive are "dynamic". That means they act on real objects. To 
understand that, look at the following equivalence:

	AnObject.Method(X, Y) <=> Method(AnObject, X, Y)

The first one is the "objet-oriented programming" syntax.

The second one is the classic programming syntax. That is what is really done 
internally.

Packet.class:

	' Gambas class

	Static Private $aType As String[256]
	Private $iId As Integer

	Public Sub _init()

	  $aType[1] = "PacketType1"
	  $aType[2] = "PacketType2"
	  $aType[3] = "PacketType3"
	  ...

	End

	Public Sub Send(hStream As Stream)
	
	End

	Static Public Sub Receive(hStream As Stream)
	
	  Dim iType As Integer
	  Dim hPacket as Packet

	  ' Read the packet type as a Byte
     iType = Read #hStream As Byte

	  ' All real packet class names are stored in the $aType array
	  hPacket = Object.New($aType[iType])
	  
	  ' The _Receive method of the specific class will be called, not
	  ' the void one in the Packet class.
	  hPacket._Receive(hStream)

	End

	Public Sub _Receive(hStream As Stream)
	
	End

2) For each different packet, you define a new class. That class will redefine 
the _Receive method, to do the real job. And the Send method also.

PacketType1.class:

	' Gambas class

	Public Sub Send(hStream As Stream, aData As Variant[])
	
	  ' aData is any array that will include the specific packet fields
	  ' You can use a Collection also, or you can define public variables
	  ' in the class, fill them, and use them directly there instead of using
	  ' an 'aData' argument.

	  Write #hStream, 1 As Byte
	  Write #hStream, aData[0] As ...
	  Write #hStream, aData[1] As ...
     ...

	End

	Public Sub _Receive(hStream As Stream)
	
	  Dim Field1 As ...
	  Dim Field2 As ...
	  ...

	  Field1 = Read #hStream As ...
	  Field2 = Read #hStream As ...
	  ...

	  ' Now you have the packets contents, you can do the real job.

	End

PacketType2.class:

	' Gambas class
	...

PacketType3.class:

	' Gambas class
	...

I hope it is more clear for you now.

Regards,

-- 
Benoît Minisini




More information about the User mailing list