Bmax Types
BlitzMax Forums/BlitzMax Beginners Area/Bmax Types
| ||
Hi Im an old time Blitz 3d user etc etc. Coded quite a bit in the old days, but have now moved to Blitz Max However I cannot get my head around the new OOp Structures with Types etc. well I think I can get my head around it but one thing puzzles me. Here is an example of some code (its not the complete code just the bits that seem to cause the problem) Basically I have created a type for a list of menus. this will hold quite a few menus, with locations (for when they pop up) headings and a few other details (I have cut most of the details out to make it simpler to view) Problem is I create a new _list to store them in but it only seems to keep the last item I create. I presume its because I have defined the _list globally somewhere and got it wrong and thus every time I call New() it has lost the last list and is starting from null (hope that makes sense) No doubt you fellas will suss out my stupidity quickly....I have spent the last 24 hours trying to get my head around what I have got wrong....other than that Im slowly getting to grips with types. I know there are probably many better ways to do what I am doing, but I just want to understand the issue before I move on to dealing with the code in a better way.... Incidently the Text I write is just to find out how many entries are in the _list I only ever get it coming back with 1 entry, and when I actually write the values it only contains the values, in this example, for Opt Menu hopefully something simple, apologies for not working this out myself :) I think the command - Global _list:TList May be causing me an issue, as I guess I may need to actually define this when creating it so that it becomes menulists_list but not sure how to explain that Kind regards, Mark |
| ||
You need to initialise your array :M.items = New String[M.totalitem] And, since arrays are zero-indexed, you do this instead For zz = 0 Until m.totalitem or For zz = 0 To m.totalitem - 1 Also, your last entry says it has 4 items... but you've only defined 3 ;-) |
| ||
this seems to work for me : |
| ||
You might also want to check : Beginners guide to BlitzMax Learning Object-Oriented Programming in Blitzmax |
| ||
Tonyg thanks for the reply. I did actually download both those and print them out yesterday. They make perfect sense to read, are very informative, but for some reason I couldn't take the examples and make them work in my code (my code is stripped from something that works in B3d, so its been converted as best I could!) Brucey, when you say it works for you, did you change anything at all? Oh hold on I will check myself :) As for the item count, yeah I stripped the 'real code' and put it in the example above, its actually got about 100 items, the idea is a user can define their own menu screens and it creates new data for them.....thus the reason I used types so I can clear unrequired screens out and add new ones on the fly. thanks again for both your help :) I will try and get it to work later tonight (they don't let me run Blizt here in work for some reason lol!!) |
| ||
So defining Local M:MenuLists = New MenuLists Instead of global makes it work? Seems back to front but I will give it a go :) I also take on board what you say about arrays starting at 0, thats just me being a bad coder and I have always counter from 1 to whatever and just loaded them that way, the idea being that I normally only grab em back based on that number. Mark Update: ah hold on, defining a Global variable in each step of the loop presumably nullifies it....so each step I create the Global, pass it to New() which creates it and ads it to the _list and then the next step reinitialises it (and clears it out I guess) before doing the same again....meaning the only version of the Global variable that stays is the last one defined. If you set it up as Local it only defines the instance for that single loop? I do appreciate Types in BMAX are brilliant, but damn its confusing when you have got your head around how they working in b3d :) I wish someone could reinitialise my global memory, then I could start from anew without presuming I know how something works :) M |
| ||
Instead of global makes it work? Seems back to front but I will give it a go :) No... it just doesn't need to be global, as you are adding the object to a TList. That was just a little code tidy-up :-) |
| ||
I will try this later. You are like my wife, tidying up all the time :) Thanks again mate. Mark |
| ||
In terms of keeping things modular, I like to use a static list within the type definition. Somewhat confusingly, you invoke these with the 'Global' keyword but, pertinently, you can have them auto-initiate on program start-up. Have a ganders at the following (some of it you will obviously know already but that particular stuff might help someone else later)...SuperStrict Type MyType Global list:TList = CreateList() ' The Global keyword signifies a class variable -- it is 'owned' by the class and shared between instances. ' The "= CreateList()" bit ensures the list is automatically created at startup. Field aValue:Int ' The Field keyword signifies an instance variable -- each instance gets its own personal 'aValue' integer. Function Make:MyType(aValue_arg:Int) ' A function is a class method -- it is something the class does rather than something an instance does. Local newInstance:MyType = New MyType newInstance.aValue = aValue_arg ListAddLast list,newInstance Return newInstance End Function Function DestroyInstance(instance_arg:myType) instance_arg.Destroy() End Function Function ListAll() Print "ListAll()" Print "=========" For Local currentMyType:MyType = EachIn list currentMyType.Report() Next Print End Function Method Report() ' An instance method -- something an instance of the class does. Print aValue End Method Method Destroy() ListRemove(list,Self) End Method End Type 'Lets make a few instances with randomly set aValue variables. For Local i:Int = 1 To 10 Local newMyType:MyType = MyType.Make( Rand(1,100) ) Next 'Now use the class method ListAll() to list them MyType.ListAll() 'The same thing, done manually from outside the class. Note we therefore use the MyType namespace to access the list. For Local currentInstance:MyType = EachIn MyType.list currentInstance.Report() Next 'Cleanup. We can do this in either a class-centric or instance-centric fashion... For Local currentInstance:MyType = EachIn MyType.list Select Rand(1,2) Case 1 Print "Called Destroy() method." currentInstance.Destroy() Case 2 Print "Called DestroyInstance() function." MyType.DestroyInstance(currentInstance) End Select Next Print "There are now "+MyType.list.Count()+" instances in the MyType list." |
| ||
Thanks guys, the amended code works a treat :) Cheers for the help.... Mark |