'Best' approach to mutliple reference of Types

Blitz3D Forums/Blitz3D Programming/'Best' approach to mutliple reference of Types

_PJ_(Posted 2015) [#1]
This is a question of technique and optimisation in terms of seeking suggestions on the 'best' way to tackle issues with multiple objects.

I am terrible at describing stuff properly, so please bear with me and I will try to explain the problem and why it's a problem!

Consider I have a number of Custom Type objects (both types of Object and number of instances) that all fulfil different requirements.

Due to the nature of the program, there is no definitive limit on the number of these objects and the number may vary greatly - this restricts the possibility of using BlitzArrays to store handles for these objects UNLESS an arbitrary value is introduced as constant maxima (BlitzArray number of elements must be constant and cannot be redefined)Standard arrays which can be resized etc. cannot be used as fields for CTOs.

Then there is the relationships between these objects with each other. In trying to show the complexity of the situation, imagine the following:

Type Person
 Field Name$
 Field PetArray[MaximumPossibleNumberOfPetsPerOwnerStoringHandlesToPetObjects]
 Field Home[MaximumPossibleNumberOfHomeLocationAspectsPerPersonStoringHandlesToLocationObjects]
End Type

Type Location
Field Name$
Field X
Field Y
End Type

Type Animal
 Field Name$
 Field Owner.Person; Required? Might make things easier, may just be overcomplicating
 Field TerritoryArray[MaximumPossibleNumberOfTerritoryLocationsPerOwnerStoringHandlesToLocationObjects]
End Type


Now a person's HOME array may contain a House, the Front Garden and the Rear Garden. Another person may just have one entry such as 'Apartment' etc.

It can be assumed that each of a person's pet animals consider their owners' home locations within their respective territory array locations. However, they may also wander into other gardens and expand their territories.

Hope it's making sense so far...

The real crux of the problem comes into play when there is potential conflict over territory between pets. The bare basics of the difficulty is (I think) a trade-off between MEMORY (using the arrays) and CPUPROCESSING/SPEED with iteration and checking.

When any individual pet enters a 'new location', should there be an iteration through every other pet and their territory arrays to identify if there is a conflict?
Or should a new list (either CTO or array) be created for territorial locations - which then introduces further checks to ensure synchronicity between the references

That's about it in a (still fairly complicated) nutshell. With the actual program, there are more levels of inter-connectivity and relationships between various groups but all along the similar principle.

I've been tying myself up in knots trying to figure out how to approach this programmatically.

There is of course, since I've recently noticed BlitzMax now freely available the extremely likely possibility that with a more object-oriented approach, there should be more scope to reference the same obejcts within other objects and even as lists of objects - though that would entail some learning of the BMax syntax etc. but it may also be an option worth considering maybe?


Matty(Posted 2015) [#2]
Iterating is not an issue (speed) if you have less than a couple of hundred to check each frame.

It all depends on how many you are expecting there to be?

Don't say you are designing for all situations - there will be a maximum number you would reasonably expect the game to cater for - in which case design around that. If there are millions use an array/memory approach. If there are a handful (dozens/hundreds) use the iterative approach.

The only time it is going to become an issue is if it is on the border of hundreds/thousands where cpu speed becomes tight and a memory approach involves a lot of wasteage (sparse arrays)


Yasha(Posted 2015) [#3]
should there be an iteration through every other pet and their territory arrays to identify if there is a conflict


No. It's worth saying that that's always the answer to a question of this form, regardless of context. Iterating over the entire universe looking for matches to a constant query is basically never the right answer to any problem. If this is a check you plan to make frequently, there should be a fast way to get the animals associated with one specific territory so you can keep the search limited to what's relevant.

Perhaps you should be giving the territories the list of pets ("synchronicity" should never be an issue. Don't let the lists be modified independently or externally, and you never have to check anything). Perhaps there's a better structure that could model this relationship (e.g. territories are arranged spatially: perhaps you don't need explicit containers; perhaps a hash space could handle this).

What's much more important is that you're massively over-thinking this. Don't be afraid to waste plenty of memory or CPU cycles while working out the design! It absolutely 100% does not matter that banks are slower than arrays or that linked-lists use lost of memory, until such time as it's actually having a measurable effect. Until then, do what's simplest: use a collection type you can fit into the design you want, so that you can express the structure and relationships you need at a high level and with the least amount of "translation" from paper to screen. You should design your program first in terms of completely abstract sets, and worry about the representation later once you know what you where you want the sets to be, and how they relate to one another. Just assume everything is fast/small enough until you have to change it.


BlitzMax's main relevant feature for you is that it has variable-sized arrays as assignable/returnable values - but you can replicate them with banks+Handle for now. Object-orientation won't help you with this at all (has nothing to do with it), so don't worry about that.


Rroff(Posted 2015) [#4]
I've not extensively tested it for performance but what you can do is make liberal use of the ability to change the order of objects in a type collection.

You'd then have a pet list type that was a child collection of pointers to the animal type - when a new owner is created you'd then make a new dummy entry in the pet list for that owner that was connected to an attribute in the owner type and move it to the start of the type collection - you'd then add list items after that dummy object for each pet connected to them - so you can then walk the list collection from that dummy object until you hit another dummy object or hit the end of the list.

non-functional code example off the top of my head:

type person
field pets.list
end type

type list
field dummy
field pointerPet
end type

type animal
end type

; create a person

this.person = new person
this\pets.list = new list
this\pets\dummy = true

insert this\pets before first list

; create an animal and add it to the list for the current person

fido.animal = new animal
temp.list = new list
temp\pointerPet = handle(fido)
temp\dummy = false
insert temp after this\pets

; walk the list of animals for the current person

temp.list = after this\pets

while (temp <> NULL)
if (temp\dummy = true) exit
; can now get each pet by doing var.animal = object.animal(temp\pointerPet)
temp = after temp
wend

If you wanted to be able to reverse walk the list then you'd have to create a 2nd dummy object to mark the end of the list.

Sorry its a bit confusing as I've not got B3D to hand to produce some properly working code - while I've not tested the performance this moves most of the housekeeping and sorting overheads into the compiled code that works behind B3D which is quite fast and should be a lot faster than iterating through it natively in B3D.

EDIT: Its also a good idea to link back the list entry to the animal so you can keep the list updated if you remove an animal, etc. (and important to keep the list updated and/or sanity check any use of the "pointer" in a list to make sure its still valid).

EDIT2: Depending on requirements you could even make the animal type collection a grouped list itself.


_PJ_(Posted 2015) [#5]
Thanks for the replies. I think I will need to clean up what I had done so far to strip it down to the bare basics and then hopefully, work with the suggestions from there.

If I encounter any further difficulty I will let you know!