Collections Tutorial
BlitzMax Forums/BlitzMax Tutorials/Collections Tutorial
| ||
Collection Tutorial Here is a small tutorial for writing collections. A collection is a set of data that can be looped through using For/EachIn/Next. Arrays are collections, so is a TList object. Collections can be the result of incrementing through a formula. I have decided to make a collection that will help emulate a For/To/Step loop. The advantage is, by changing the data in the collection, you can change the any of the values, including Step, even during the loop. Really nice if, for instance, you want to use one For/Next loop to draw a grid, but the grid spacing, and therefore the Step value, can change dynamically. To start with, we will put SuperStrict at the top of the program. SuperStrict will help catch many errors and make debugging much easier. SuperStrict Next we will create the type. We will put in a Global called Data which will point to an instance of the type. this instance needs to be created since BlitzMAX will ask for one when we enter the For/EachIn loop. Also we will put in Globals called _From, _To, and _Step, which will represent the From, To, and Step fields of a For/Next loop. I'm using an underscore so as not to create conflicts with the BlitzMAX built in commands. Lastly there is a Field called Current which will represent the current value of the loop. Type TLoop Global Data:TLoop Global _From:Int, _To:Int, _Step:Int Field Current:Int Now we will create a function Set() which will create a new object for Data, and will set all the fields for us. Function Set(_From:Int,_To:Int,_Step:Int) Data = New TLoop Data._From = _From Data._To = _To Data._Step = _Step End Function Now, before we actually enter the loop, we set the fields like this TLoop.Set(100,200,10) Where the first number is the From field, the second is the To field and the last is the Step value. Next we need to create the ObjectEnumerator() method. When the For/Eachin loop is first entered, BlitzMAX will call this method which will then return an Enumerator type. Since TLoop is the Enumerator itself, it'll just return the TLoop object stored in the Data global. Before it returns though, it will set Current to the _From value minus the _Step value. We are subtracting the _Step value, because through each iteration, we will be adding the _Step value and checking it against the _To value, so that _From value itself will be returned the first time through the loop, we are starting at a lower value. There are other ways of doing this also, such as setting a flag and only incrementing the Current Field on the second and later iterations. Method ObjectEnumerator:TLoop() Current = _From - _Step Return Data End Method Next we are going to create the HasNext() method. Through every iteration of the loop, BlitzMAX will call HasNext() and it will return either True if there are more items in the collection, or false if all the items have been returned. Our HasNext method will just add the _Step value to Current and compare it to the _To value. There are two comparisons depending on whether the _Step value is positive or negative. Method HasNext:Int() Current :+ _Step If _Step > 0 If Current <= _To Then Return True Else If Current >= _To Then Return True End If Return False End Method Next is the NextObject() Method. When HasNext() returns True, BlitzMAX will call NextObject() to get the actual object. Here, we just need to return Data. Method NextObject:Object() Return Data End Method End Type And that's it for the type. Now we will just create some code to test. First the code calls TLoop.Set(0,100,5) to set the parameters, then uses For/Eachin to do the actual looping. There are three loops in this example, the third one using a negative step value TLoop.Set(0,100,5) For Local Loop:TLoop = EachIn TLoop.Data Print Loop.Current Next Print "~n" TLoop.Set(100,200,20) For Local Loop:TLoop = EachIn TLoop.Data Print Loop.Current Next Print "~n" TLoop.Set(500,400,-5) For Local Loop:TLoop = EachIn TLoop.Data Print Loop.Current Next Here is the code in it's entirety. You can look at brl.mod/linkedlist.mod/linkedlist.bmx for another good implementation of collections |