Spherical forums

User-Made => Libraries => Library Support => Topic started by: Radnen on June 27, 2013, 05:06:32 am

Title: [persist.js] Using 'self' instead of 'this' in persist
Post by: Radnen on June 27, 2013, 05:06:32 am
So, for some reason I cannot modify values in a persist object. I set up a store, like this:

Code: (javascript) [Select]

({
    Shop: {
        items: ["item", "item", "item"],

        talk: function() {
            ShowShop(this.items);
        },
    },
});


I then commence to trade and modify the list of items so it reads: ["item", "item", "item", "item"]

Then I do this test on the persist object:

Code: (javascript) [Select]

var world = JSON.stringify(persist.getWorldState());

Debug.alert(persist.getWorldState()[GetCurrentMap()].Shop.items);
Debug.alert(JSON.parse(world)[GetCurrentMap()].Shop.items);


And I get two very different results. The JSON object will only show the original list of items, while the direct source will show all of the items. Because of this issue I can't save modified lists of stuff, and I have no idea why.

I then see inside the persist code this gem:
Code: (javascript) [Select]

    /* Tie an existing object to a prototype. */
    function tieToPrototype(obj, proto)
    {
        var protoTie = function () {};
        protoTie.prototype = proto;
        var newObj = new protoTie();
        for (var p in obj) {
            if (p in proto && typeof proto[p] == 'object')
                newObj[p] = tieToPrototype(obj[p], proto[p]);
            else
                newObj[p] = obj[p];
        }
        return newObj;
    }


And for some reason I think this may be what's interfering. If I can't solve this problem, then persist has sadly, defeated itself for me.

For one, persist will convert all arrays into objects. Ouch!

Furthermore I can't seem to do this:
Code: (javascript) [Select]

persist.map().Shop.new_var = true;


When I go through the JSON motions, the value 'new_var' that I instantiated after the load had been stripped. Despite being added in after the fact, it won't save to file, calling 'toSource()' on the object also won't unveil it in it's list of fields, however if I use the '.new_var' field it's there; it exists. Tung seemed to have removed many idiomatic Javascript features in his persist wrapper. Can someone far brighter than me in this matter help me rewrite his code to not have this behavior?

Furthermore, values if changed produce whacky outputs. When I tack on a 'visited' member, set initially to false. I always get false back from it. Even if I set it to true... unless I'm using it directly within the scope of the person or map, then it seems to work out. I have no idea why this is happening.

Edit:
Wait... It's working EVERYWHERE ELSE but that file of code. WTF?
Title: Re: Trouble with persist
Post by: Radnen on June 27, 2013, 06:06:29 am
Solution: Don't use 'this' anywhere in your persist code.

The talk code once changed to this will work:
Code: (javascript) [Select]

({
    Shop: {
        items: ["item", "item", "item"],

        talk: function(self) {
            ShowShop(self.items); // importance of self
        },
    }
});


I have no idea why, and I feel there is something really fishy about this. Persist is supposed to be an analogue for map persons. I don't know why tung had to do this weird prototype shuffling?

Edit:
oops, I think this is in the wrong spot. I thought Sphere support was also game JS support too? I never realized it was for editor / engine only. Oh well, old habit.
Title: Re: Trouble with persist [closed]
Post by: DaVince on June 27, 2013, 09:50:06 am
Quote
oops, I think this is in the wrong spot. I thought Sphere support was also game JS support too? I never realized it was for editor / engine only. Oh well, old habit.

Seems like the right spot to me if you check what subforums there are.
Title: Re: Trouble with persist [closed]
Post by: N E O on June 27, 2013, 05:49:16 pm
Re using 'self' instead of 'this' in persist - I recommend updating the wiki article (http://wiki.spheredev.org/Script:Persist.js) as needed to reflect this finding :)

Re proper board for script help - while I wrote the original guideline as "Support for scripts, resources, or projects should be in their appropriate threads since this sub-forum is for app support." it seems I neglected to take into account a few situations. I'm making a board "Library Support" under User-Made for things like this and will move this and rename with a prefix.
Title: Re: [persist.js, closed] Using 'self' instead of 'this' in persist
Post by: Radnen on June 27, 2013, 06:32:01 pm
Actually, I'm still having problems with lists.

So some things are indeed working, but when I modify a persist list I get weird cyclical issues. I buy an item and another item is added at the end of a list. I splice elements out of the list, and then new elements are re-entering at the end. Why?
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: Radnen on June 27, 2013, 06:41:46 pm
Alright, new issue with persist: it likes to merge. Good for properties, bad for lists.

So the items list has 15 items. When you buy items it goes down to say 12 items. I then save the game and reload and I get back the 12 items in the list, but then it adds the three items from the old list to return back to 15 items. I wonder how to turn this 'merging' off.
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: Radnen on June 27, 2013, 08:35:42 pm
Fixed!

I wrote my own persist script from grounds-up. :) Supports idiomatic JS and all kinds of cool things like using the 'this' pointer. Really it just loads the existing persist format as a standard JS object. You can modify it however you want, save it, load it, etc.
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: N E O on June 27, 2013, 09:04:34 pm

I wrote my own persist script from grounds-up. :)


Groovy :) How about a Gist or something then?
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: Radnen on June 27, 2013, 09:19:16 pm
Well it's not as well documented as his and as tested. But the preliminary tests pass, I fixed my issues that I had so far.
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: alpha123 on June 27, 2013, 10:11:44 pm
I've had all sorts of weird issues with persist as well. It's doing some really bizarre black magic that I understood at one point (I've hacked on it a lot) but now forgot about. :P

The attached version might fix some of the issues you're having Radnen. I'm not sure if it has any other dependencies, but I don't think so. There are a small number of other changes, but I don't remember them sadly. :( (It's been a while since I last worked on persist - ATM this version does what I want it to, fairly bug-free.)
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: Radnen on June 27, 2013, 11:45:42 pm
Thanks alpha123 but it still has other issues, and you've put in some dependent code in it, that I had to hack around to get it working.

RadPersist is nice and lightweight (142 LOC), but it requires some dependent pierces of code so I don't want to just drop it somewhere. I'll have to create a stand-alone version (not that much trouble, just some minor changes).
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: Fat Cerberus on June 28, 2013, 01:33:51 am
I'm glad you discovered all this now, Radnen. I just started work on Spectacles proper (as hard as it's been to stop playtesting the battle engine; it's a lot of fun, even without proper graphics!), so it's good to know about it now before it bit me in the ass and I had to create this very same thread. :P

So needless to say, I'm interested in RadPersist as well.  How did you pull off doing it in ~150 LOC though? That's impressive!
Title: Re: [persist.js] Using 'self' instead of 'this' in persist
Post by: Radnen on June 28, 2013, 01:39:05 am

I'm glad you discovered all this now, Radnen. I just started work on Spectacles proper (as hard as it's been to stop playtesting the battle engine; it's a lot of fun, even without proper graphics!), so it's good to know about it now before it bit me in the ass and I had to create this very same thread. :P

So needless to say, I'm interested in RadPersist as well.  How did you pull off doing it in ~150 LOC though? That's impressive!


No logging, no state ensuring - whatever the hell that was, and no major comments. It got somewhat larger when I made a standalone version. Check out 'analogue.js', it's still under 175 Loc though!

I wanted it to behave more like JSON than what tung had (no offense to tung's). So you can use 'this', you can initialize at will, and still do what the old persist did with 'self'.