Forum BigDB Circular Reference error - bug?

Discussion and help relating to the PlayerIO database solution, BigDB.

Circular Reference error - bug?

Postby markloika » August 11th, 2011, 9:17 am

Hey,

I have this code:

Code: Select all
PlayerIO.BigDB.LoadOrCreate("WorldObjects", slot.id, delegate(DatabaseObject saveObject)
            {
                DatabaseArray chunks = null;
                if (saveObject.Contains("chunks"))
                {
                    chunks = saveObject.GetArray("chunks");
                }
                else
                {
                    chunks = new DatabaseArray();
                    saveObject.Set("chunks", chunks);
                }
                chunks.Clear();

                foreach (DatabaseObject chunkObject in slot.chunkObjects)
                {
                    chunks.Add(chunkObject); //Circular reference error
                }

                saveObject.Set("name", slot.name);
                saveObject.Set("creator", playerKey);
                saveObject.Set("width", slot.width);
                saveObject.Set("height", slot.height);

                saveObject.Save(false, delegate()
                {
                    callback(true);
                }, delegate(PlayerIOError error)
                {
                    callback(false);
                });

            }, delegate(PlayerIOError error)
            {
                callback(false);
            });


This code runs perfectly the first time I run it in a server room, but if I run this a second time, it thinks there's a circular reference. I think it thinks there's a circular reference because in the 'slot.chunkObjects' list, some of those chunk objects are not modified from the last time this function is called. Therefore, when the chunk object is added again to a database array, it somehow thinks there's a circular reference. This is strange, because the database array is cleared before the new items are added to it - but that shouldn't even matter because it would be impossible for something in memory (objects in the slot.chunkObjects list) to have a reference to a 1) newly instantiated database array, or 2) an object I just loaded from the database.

Maybe I'm looking at this all wrong, and there's some obvious answer, if so, please share :)

I've spent quite a bit of time at this, any help would be appreciated.
markloika
 
Posts: 76
Joined: July 8th, 2010, 3:46 am

Re: Circular Reference error - bug?

Postby Oliver » August 11th, 2011, 7:21 pm

Hey Mark,

The code snippet you posted is not big enough to get a proper feeling for what you´re trying to do. Is it possible to paste the offending piece of code into a NewGame project such that you also get the error there and send it over as a complete project?

Best,
Oliver
User avatar
Oliver
.IO
 
Posts: 1159
Joined: January 12th, 2010, 8:29 am

Re: Circular Reference error - bug?

Postby markloika » August 11th, 2011, 10:02 pm

I have distilled my code into the following few lines:

Code: Select all
DatabaseObject databaseObject = new DatabaseObject();

            DatabaseArray array1 = new DatabaseArray();
            array1.Add(databaseObject);

            DatabaseArray array2 = new DatabaseArray();
            array2.Add(databaseObject);


The error occurs when I try to add databaseObject to array2. Two different database arrays cannot reference the same database object.

What I'm trying to do is save my world (200x100 tiles) to BigDB. A world is comprised of chunks, which is 50x50 blocks. Every chunks has a database object, it is an array of these database objects that is saved to BigDB. Every time a block is mined or placed, the database object is re-created by the chunk class. When the player clicks the save button in-game, the server loops over all of the chunks, gets the database object, and adds the database object to an array. Not all chunk objects are modified between saving the first time and saving the second time. This causes an issue - the chunk objects are created only when the chunk is modified, so if the chunk is not modified, a new chunk object is not created the second time the save function is called. This makes sense - it would not be efficient to re-create all of the chunk objects when the save function is called, it would most likely lead to server aborts. Avoiding server aborts is the entire reason chunks exist in the first place. The first version of Block Miner looped through every block in the world when the save function was called - this led to server aborts. Using the new method, the chunks are already ready to be saved when the save function is called, therefore eliminating the need to loop over every block in the world.
markloika
 
Posts: 76
Joined: July 8th, 2010, 3:46 am


Return to BigDB



cron