Reputation: 911
So I looked around a bit a lot of broken links and explanations over my head.
I am asking this for a gaming application so for example an owner will have an item and the item is also held by the owner.
My server has no problem storing circular references. but I send the player object to the client when the client first signs in. I am having trouble wrapping my head around how to do this. items can be held by a player in inventory slots such as the players sack hands on their head... an item could also be on the ground at an x,y location I've considered having some kind of container with an id that just acts as a pointer. rather than passing a JSON string object.
being able to pass circular objects would be great or a simple function that can use an Id to refrence where an item is would work.
Here is my best attempt at a solution
//create an object
// run this function
function createRefrence(ref){
container = io.sockets.containersById.push(ref)
io.sockets.containersById[container-1]={ref:ref}
return (container-1)
}
//storing the return value as a property of the object
Upvotes: 1
Views: 151
Reputation: 1851
The short answer is don't! The circular references don't get you anything really. There are three basic ways of representing this kind of data in a non-circular way. You're heading in the right direction when you say just have an id as a pointer.
The way I'd do this is rather than trying to have one huge object, which contains all the others have a data format which lists the user's character, and just references the items, but doesn't actually put them within the character's data structure.
Each object would have an id of some kind which then connects the two. Doing this in XML (for want of a better syntax) could look like this...
<character>
<possession ref='1' status='worn' />
<possession ref='2' status='inventory' />
</character>
<world>
<item ref='3' xpos='3' ypos='4' />
</world>
<object id='1' name='clothing' hp='12' />
<object id='2' name='gadget' hp='0' />
<object id='3' name='cash' hp='0' />
When you parse that you see the refs connect the object to the character or to the world. So as you build the actual objects you'd give them each references to each other.
Alternatively you could do something like this...
<character>
<object id='1' name='clothing' hp='12' />
<object id='2' name='gadget' hp='0' />
</character>
<world>
<object id='3' name='cash' hp='0' />
</world>
Again, note that while the object being owned by the character is explicit the link the other way is implicit and your parser would have to know to rebuild that.
Or you could even do something akin to a link table a la SQL where the connections are entirely removed from the other objects and externalised. The nice thing about this form is that there's nothing implied. The bi-directional links are very clearly stated and the parser to rebuild them would be very simple.
<character id='1'>
...
</character>
<object id='1' ... />
<link character='1' object='1' />
Of course the same semantics can be represented in the format of your choice, so you could do this in JSON or your preferred format.
You may also find this useful, https://stackoverflow.com/a/3341439/51031 which gives some options for libraries which can be told to exclude some links, but the problem remains as to how you stitch the objects together again when you deserialise. So one way or another you're going to end up writing some parsing code sadly!
Upvotes: 2