Re: [Gambas-user] gb3 RC1: using structures to replace the loss of Mk$ functions
Brought to you by:
gambas
From: Benoît M. <ga...@us...> - 2011-04-03 07:11:14
|
> 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 |