Add functionality to memory objects
-
Hmmm never tried that.
Turns out the exact same thing happens.
-
Ok so I've been taking a look at this a little more and it seems like what I'm trying to is legal. I will put this in the bug section and see what happens there.
-
@grandpa_sam No this is not legal, Memory is for storing plain data only.
setPrototypeOf
should be the solution.
-
As I said before.
setPrototypeOf
has the exact same problem with the exact error.Also from what I've read and tested, directly adding a function to an objects prototype would not be saved because
JSON.stringify
ignores functions all together
-
Works fine for me.
JSON.stringify(Object.setPrototypeOf(JSON.parse(JSON.stringify(new RoomPosition(28,36,'W23S82'))),RoomPosition.prototype).look())
Here what we do here:
new RoomPosition(28,36,'W23S82')
creates an object with methods and everything, thenJSON.stringify
makes a serialized data, thenJSON.parse
makes plain data object (the exact same thing you get at next tick if you store it in memory), thenObject.setPrototypeOf
makes the objectgreat againa valid RoomPosition object, thenI test it with
RoomPosition.look()
method.Result:
[ { "type": "structure", "structure": { "room": { "name": "W23S82", "energyAvailable": 2300, "energyCapacityAvailable": 2300, "visual": { "roomName": "W23S82" } }, "pos": { "x": 28, "y": 36, "roomName": "W23S82" }, "id": "5bd465b4561835306e59ff9b", "store": { "energy": 153780, "XKH2O": 79728, "XZHO2": 19849 }, "storeCapacity": 1000000, "owner": { "username": "o4kapuk" }, "my": true, "hits": 10000, "hitsMax": 10000, "structureType": "storage" } }, { "type": "structure", "structure": { "room": { "name": "W23S82", "energyAvailable": 2300, "energyCapacityAvailable": 2300, "visual": { "roomName": "W23S82" } }, "pos": { "x": 28, "y": 36, "roomName": "W23S82" }, "id": "5bd709123bdc376787ae3146", "ticksToDecay": 14, "isPublic": false, "owner": { "username": "o4kapuk" }, "my": true, "hits": 794701, "hitsMax": 30000000, "structureType": "rampart" } }, { "type": "terrain", "terrain": "plain" } ]
UPD While you can store objects to memory and restore them from there, you're not supposed to do that. I'm serious, don't do that. This is bad. You're better than this. Make it stop...
-
Ok cool. Thanks for your help. I must be doing something wrong with this. I will get back here with more information.
EDIT: also clever joke. When I re read it I laughed
-
Ok I have a question on your edit. Are you saying that while technically Object.setPrototypeOf would fix my problem, I shouldn't use it and instead should try a different line of thinking?
I'm not at all trying to save anything but the data inside the objects but I would like to be able to keep my key functionality pertaining to the data in those objects in one place preferably nicely wrapped up in the object prototype itself.
I guess my goal here is when its time to save to memory I rip all the data out of the class. Then on the next tick when its time to load I put that data back into a new instance of the same class made that tick.
-
Well, I personally solved it with wrappers. Basically, I create a plain data object like this:
{ "id": "75912f1f-dd4d-4665-9ae7-058fc12710cd", "priority": 15, "subtasks": [], "lootObjectId": "5b78ab2cd6d21b3580d38768", "position": 1095405321, "type": "lootResource", "isCompeted": false }
Then, when I need to work with this data in object-oriented way, I create class passing reference to the object to its constructor. The class saves this reference and work with these data directly like this:
getPriority: function() { return this._data["priority"]; } setPriority: function(newValue) { this._data["priority"] = newValue; } getLookObject: function() { return Game.getObjectById(this._data["lootObjectId"]); }
And so on. This way, I don't need to bother about prototypes or something, plus I don't have to explicitly 'save' data from work objects to a plain data object; also work objects may be efficiently cached in heap, again, without any dancing around data updates.
Of course, this is not the single best way of doing things, custom serializers may be better (noticed "position" property?).
-
Ok great,
Thanks for having this discussion. I'm at work so I can't test this stuff but you have given me multiple paths to explore so I'm going mark this as resolved.
Thanks again for your help.
-
@grandpa_sam You welcome
-
As a sidenote, I believe you can call a function onto objects it's not a part of. Here's an example with my Species class when reviving a deceased creep :
let species = Memory.species[creep.memory.species]; let body = SpeciesClass.prototype.findByCost.call(species, energyAvailable);
That last line would work the same as if
species
were an instance ofSpeciesClass
and I wrote :let body = species.findByCost(energyAvailable);
(Though to be honnest it's part of a module I haven't fully tested yet)
-
Thanks for the info Estecka. I will look into that as well.
-
However watch out for nested function calls. In my example, if
findByCost
tried internally to call more functions fromSpeciesClass
with the usualthis.function()
syntax then it will fail.
For every functions that you plan to call onto "foreign" objects, make sure all nested methods are called using theYourClass.prototype.function.call(this)
syntax.