Shortening Nested Type

Blitz3D Forums/Blitz3D Beginners Area/Shortening Nested Type

-Rick-(Posted 2009) [#1]
Got a question here. Been muddling through the forums to find information on having types within types and think I've gotten it figured out. But I'm ending up with a monster of a line of code to type in for a single variable. I have 4 types : Universe, Galaxy, System, and Planet.

So if I want to enter data on a planet I'm using something like this :

u\galaxy[g]\system[g]\planet[p]\data

Can I shorten that somehow for simpler coding? Like just a

planet[p]\data

Tried the above and that doesn't work. But is there another way? Or do I have to type it all in?

<edit>Not sure if this info will help, but have 1 universe holding 36 galaxies each with 499 systems with 15 planets in each of those.


Stevie G(Posted 2009) [#2]
If you are going to be accessing the data often in a function then you can do something like ...

local p.planet = u\Galaxy[g]\system[s]\planet[p]
p\Data = blah 



-Rick-(Posted 2009) [#3]
Nice. Didn't think of that ... I'll have to save any changes with p.planet to the u\galaxy...\data tho right? Hmm... wonder if after any changes I could do something like

u\Galaxy[g]\system[s]\planet[p] = b.planet

Would that automatically fill in all the fields? Will have to look into that and see.

Thanks again!


Yasha(Posted 2009) [#4]
You don't need to bother with that last step. Type objects are passed by reference rather than by value: the variables you manipulate directly are actually pointers (which is why 1. they can be Null, and 2. they need to be explicitly assigned an object with New). When you say
local p.planet = u\Galaxy[g]\system[s]\planet[p]
p\Data = blah

you aren't creating a new instance of type planet; you're merely setting the pointer p to the same address as the pointer u\Gal...\planet[p]. If you like you can think of this as meaning that any changes you make to p will automatically update u\Gal...\planet[p], but the fact is that they're the same object so no updating is necessary at all.

Effectively this is the same as copying the integer handle of a 3D entity to another int variable; there's still only one object, but now two copies of its address. The only difference with type objects is that their type is checked at compile-time.


-Rick-(Posted 2009) [#5]
Thanks Yasha and Stevie

I'm having a little more trouble and I'm not having much luck in figuring out what I'm doing wrong.

What is happening is that I'm making up the types but when the program runs they aren't there. I thought maybe is was a global assignment issue, but if it is, I can't figure out the correct syntax in doing it.

Here is what I Basically have in Types :

Type Planet_Info
    Field blah, blah, blah
End Type

Type System_Info
   Field blah, blah
   Field planet.planet_Info[15]
end Type

Type Galaxy_Info
   Field blah,blah
   Field System.System_Info[499]
end Type

Type Universe_Info
   Field Galaxy.Galaxy_Info[36]
End Type

Global U.Universe_Info = New Universe

Initialize()

Function Initialize()
	For g = 1 To TOTALGALAXIES
		U\galaxy.galaxy_info[g] = New galaxy_info
		For s = 1 To TOTALSYSTEMS
			u\galaxy[g]\system.system_info[s] = New System_info
			u\galaxy[g]\system[s]\num = s
			u\galaxy[g]\system[s]\Galaxy = g
			For p = 1 To TOTALPLANETS
				u\galaxy[g]\system[s]\planet.Planet_info[p] = New planet_info
				u\galaxy[g]\system[s]\planet[p]\planet = p
				u\galaxy[g]\system[s]\planet[p]\system = s
				u\galaxy[g]\system[s]\planet[p]\galaxy = g			
			Next
		Next
	Next

end Function


I'm pretty sure some of that (if not all) in the Initialize function is redundant - at least I'm starting to think I don't need that since I declared how many galaxies, systems, and planets there were in the Type.

I had assumed that when I globally created U.Universe_Info that the rest would be right there so that I could write or read it, but the program says it doesn't exist. That's why I went with the Initialize routine, to actually create each one. But again, when the program runs it says nothing exists.

In debug mode in the globa variablel region I do have
U.Universe_info
     Galaxy.Galaxy_Info[36]


But thats where it stops. No system or planet types were made. Also, the U.Universe_Info global has a + sign which I can open to see the Galaxy.Galaxy_info[36], but there is no + on galaxy to show me the system and planet types.

So at this point I'm a bit lost. Thought I was being brilliant by deciding to keep everything in nested Types so that I could easily call the information and it would be easy to write to and store it as a single file. It's been a few years since I picked up Blitz and tinkered so I just don't recall the proper way of doing it. Tried searching the forums but looking for "Type within a Type" or "Nested Types" didnt' seem to reveal what I needed.

Sorry to be a bother on this. But its the one thing really hanging me up.


Stevie G(Posted 2009) [#6]
What you need to think about is what information you need from each of the types. For example, do you need to know which system each planet belongs to or which galaxy each system belongs to? You may not need this if you are directly accessing the details by knowing the galaxyno, systemno and planetno. Let me know.

This should give you a start. I put in a quick function to let you see all the planets which have been created for each system in a specified galaxy. Sorry no time to explain - off to work just now ..




Yasha(Posted 2009) [#7]
What leaps out at me in your (-Rick-) code above is that, while your galaxy loop is fine, the nested For loops within it - for system and planet - aren't doing anything.

In the system loop, you're declaring "sys" as your iterator. You're then using "s" as your array index. "S" never changes (it's never even set), so you're simply assigning each new system to index zero (which you'll probably never see anywhere else as you're counting from 1). In the planet loop, you've declared "pla" as your iterator and are using "p" as your array index - again, never changes and every object gets assigned to index zero repeatedly.

The other thing to bear in mind is that the Blitz3D debugger doesn't let you expand arrays in the side bar, so you'll never get a + next to u\Galaxy - you'll need to think of a different way of displaying its contents if you need to check on them.

I really, really strongly suggest that you get IDEal (if you haven't already) and turn on Strict mode, and leave it on. This will catch such errors for you at the coding stage (Strict in IDEal is different from Strict in BlitzMax - infinitely better, in fact - in that it doesn't wait until you hit compile or run, but rather highlights undeclared variables in red as you type). You'll need to get used to explicitly declaring things as Local a lot, but this is better practice than using implicit declarations, which are the road to misery (it'll also train you well if you ever want to move over to a C-like language, as C and its children don't allow implicit declaration at all).


-Rick-(Posted 2009) [#8]
Oh sheesh. Yah, the nested loops. That "sys" should be a simple "s". Now I wonder which of the thousand different things I tried would have worked if that stupid "sys" variable had been correct there.

Just saw this at home, will try changing that out and look closer at Stevie G's code when i get to my shop computer.

Thanks for the time guys - and Happy Thanksgiving. I'm definitely thankful for your giving!


-Rick-(Posted 2009) [#9]
Sorry Yasha, your right, those were bogus variables left over from when I was having conflicts with 'g' as a count variable and 'g' as new type. Didn't matter anyway because I was doing it wrong.

Stevie, thanks for that. I FINALLY got it working in my code to create the various types. I am completely unfamiliar with the usage of functions with that '.' separator in them. Took me nearly 45 minutes to catch that in my code because I kept getting an error on 'Illegal Type Conversion' that was driving me absolutely batty.

And from that I move into my next confusion. When you do the information pull you use a string to read information. It creates a '[1,10,4]' sorta thing. That absolutely confuses me.

First, where do the brackets come from? lol. Never mind, was just a rhetorical question.

I guess the real question is how would I access specific data and write to it? I'm still getting errors if I use the u\galaxy[g]\system[s]\planet[p] format to write to a specific area.

Lets say I have a field in the Planets_Info Type called 'PlanetName$' that I want to either read from or write to. I know the galaxy number, the system number and the planet number and I want to read the information from the planet.

Concurrently, if I have a field in the Planets_Info Type called 'Ore' which reflects how much ore is on the planet and I want to update that with a new amount, how would I write to u\galaxy[g]\system[s]\planet[p]\Ore ?

Trying to use that format gets me an "Object Doesn't exit" error. It's really throwing me off that the types aren't listed in the debug area. THe U.Universe_Info global is there and within it I see Galaxy.Galaxy_Info - but that's as far as it goes. I get the same result with the code example you provided. So its like the system_info and Planet_info are in some limbo somewhere that I can't verify exists, but in your code you showed it does by pulling up the data you put into it.

I really thought this would be the better way to go - nested types so I could just pull up the information if I knew the galaxy, system, and planet number. Starting to pull out my already short hair! lol. Your help is very appreciated!


Stevie G(Posted 2009) [#10]
In the code above use the following function to get the planet type you want to amend.

Function PLANETget.Planet_Info( GalaxyNo, SystemNo, PlanetNo )

	Return U\galaxy[ GalaxyNo ]\system[ SystemNo ]\planet[ PlanetNo ]

End Function


So, say you wanted planet 3 from system 2 from Galaxy 5, just do ..

p.planet_info = PLANETget( 5, 2, 3 )
p\Ore = 120


For info, the reason I used str$() in the print routine is that it allows you to view the contents of a Type, the different values are held between the [] brackets.

Stevie


-Rick-(Posted 2009) [#11]
<edit>
Posted before I knew you posted Stevie. Let me try out what you said (in case you read my previous frustration ramble) and I'll see if I can finally get my head around this.


-Rick-(Posted 2009) [#12]
Nope. Still not working.

Everything goes in fine and apparently the syntax is correct. But when I try and use GETplanet I get an "Object Doesn't Exist" whenever I try and use the p\data call.
Type Planet_Info
	Field PlanetName$,PlayerName$
        Field Ore
End type

p.planet_info = PLANETget(gal,sys,pla)
p\planetname$ = planetname$  <-----generates object doesn't exist error. Confirmed that field exists.
p\playername$ = player\name  <-----Object doesn't exist (player/name does, but not p/playername)
p\ore = Ore   <-----------Object doesn't exist
.
.
etc

Function PLANETget.Planet_Info(g,s,p)
		Return U\Galaxy[g]\system[s]\planet[p]
End Function


I've followed the code through line for line as it ran. It goes to PLANETget, the galaxy,system, and planet values reflect the right coordinates, and after the RETURN the variable list shows p.planet as NULL and I cannot do anything with it without getting a Doesn't Exist Error.


_PJ_(Posted 2009) [#13]
In your Initialise function, you are using 'pla' not 'p' for the planets, and 'g' not 'gal' for your galaxies.

Keep your local references separate from global ones, I find it really helps to declare Locals with Local withi each function, it bloats stuff a bit, but sure makes it quicker to spot stuff :)
(especially with IDEal ;) )


-Rick-(Posted 2009) [#14]
Right, that was pointed out earlier and already corrected. The only time I change up on variables like p or pl or pla is if I start to run into conflicts. When I put my code above up I was having that issue where it was saying I was having duplicate identifiers. But its all cleared up now. I'd rather go with more descriptive variable names than simple letters because I lose track of what goes where fast.

Still not having 1 bit of luck on getting this stupid thing to work. Stevie's example was great because it showed me stuff I didn't know, but the examples he gave don't fit the circumstances I need. His suggestion for creating the type looks great, has no syntax arguments with Blitz, but when it runs it just doesn't do anything but create null types.

So far everything that I've done wrong has been some stupid thing so I'm sure I've got yet one more stupid thing to figure out.


Stevie G(Posted 2009) [#15]

His suggestion for creating the type looks great, has no syntax arguments with Blitz, but when it runs it just doesn't do anything but create null types.



Nonsense - it works fine here so you clearly are not using is correctly. According to your posts the examples fit your needs perfectly. Post what code you have and someone can tell you where you're going wrong.


_PJ_(Posted 2009) [#16]
I'll try and have another look over it soon - right now, the nested types just gets too confusing to trawl through at the moment.

I still think that at some point, a Type is confused with a variable, but just where that happens I'l have to get back to you...


-Rick-(Posted 2009) [#17]
I think I may have found my problem. As I said, it was a stupid one. It was a bit of code left over from before getting help here that was deleting the planet_info types.

That's why I was so confused as to why it worked in your example and not in my code Stevie. I wasn't doubting your advice and examples at all - they made sense and the examples worked. It was just so frustrating to KNOW it works yet it won't work inside my own code.

While trimming the code to post it on here I found the problem. I wanted to make sure you had a running version that you could see where error was coming up. That's when I spotted the Delete Planet_Info line that caused all this extra hassle.

Since taking it out the initial tests have FINALLY run correctly. I'm not getting the "Object doesn't exist" error. The data is now there and I can access and write to it. PERFECT!

I'm sorry I was such an idiot with this and I really thank you for the time and effort you invested. And thank to Malice for giving a look too. I just can't express enough my appreciating for the help you guys have given me to get past this.


_PJ_(Posted 2009) [#18]
:) Phew, glad you sorted it so I dont need to strain my eyes again hehe!

Glad to help, not that I did much! But it's the same with me, the most confusing problems are usually the result of the tiniest, stupidest errors. I'm sure we all do it and that's what these forums are here for!

I actually like this therad, because I have a kinda side-prioject thing going which will deal with building the solar system, so instead of say, galaxies/stars/planets I will have sun/planets/moons the concept of nesting the types is something I hadn't thought of before(probably why it was so hard for me to follow what's been done here) but it's an inspiration for how to tackle my own.


-Rick-(Posted 2009) [#19]
I tried that before, Malice. I wanted an accurate scale of the solar sytem with planet inclination, orbital paths, moons, rotation, acurate sun,planet and moon size etc. I ran into the problem with big numbers vs tiny tiny numbers. The rounding goes haywire on you! I was trying to create a cool tutorial about our solar system so people could see the scales and stuff.

If you go by scale remember to keep that in mind. The solution I considered was to separate things into blocks of size. So trying to draw a moon at position .0000000001 and a planet at 100000000 doesn't create that huge discrepancy in range.

It looked really cool cause I did it in blitz3d and had meshes for the moons as well as high texture for the planets. It's been a while now so I don't remember the link, but there was a guy who had the latest NASA surface maps of stuff and moons that hadn't been scanned had been very creatively created using long range pictures. He also had very detailed meshes of nearly everything. I had to reduce the meshes quite a bit because they were massive.


_PJ_(Posted 2009) [#20]
Exactly what I'm wanting to do - a failry accurate solar system representation.
I know the scale is gonna be an issue, I'm thinking of using a kind of level of detail system where you need to 'zoom-in' on a plabnet to see the moons for example and maybe the varius bodies will simply be sprites until you get close enough to reveal them as the proper meshes etc. I'll see how it goes, right now, I'm still collecting all the data :D