[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