Skip to main content

News

Topic: Link.js v0.4.2 (Read 97676 times) previous topic - next topic

0 Members and 3 Guests are viewing this topic.
  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #165
Hm, Link.invoke() with arguments is broken.  It passes the function itself as this instead of the object it's called on.  I ended up breaking my whole Stance system because of this, it took me a half hour to figure out what happened! :'(
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #166
I don't know why here is where the args are passed into the invocation:

Code: (javascript) [Select]

InvokeArgsPoint.prototype.exec = function(item) { item[this.name].apply(item[this.name], this.args); }

InvokeArgsPoint.prototype.run = function(a) {
var i = 0, l = a.length, n = this.name, args = this.args;
while(i < l) { var m = a[i++][n]; m.apply(m, args); }
}


In both cases I clearly pass the object to it. Wait. I see the issue. I think I'm passing the function to itself. Let me fix this, yikes!
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #167
I knew I wasn't going nuts!  How I finally discovered the bug was when I added an Abort call on this in one of my invoked functions--it printed out the function body!
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #168
Fixed. :P
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #169
So I'm writing the AI for one of my bosses, and I'm wondering, is there a way to do the following in Link?
Code: (javascript) [Select]
var targetID = null;
var maxValue = 0;
for (unitID in this.damageTaken) {
if (this.damageTaken[unitID] > maxValue) {
targetID = unitID;
maxValue = this.damageTaken[unitID];
}
}


I know Link has the max() operation, but if I'm understanding it correctly, that only gives me the value.  What I actually need as output is the unit ID, which is a string--damageTaken is an associative array.
  • Last Edit: May 07, 2014, 10:07:54 am by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #170
Why are you storing damage in an associative array? If damageTaken was an array of { id, value } objects then Link would work perfectly for you.

Code: (javascript) [Select]

var item = Link(this.damageTaken).max(function(item) { return item.value; });
item.id // the answer you are looking for.


I could somehow try and do a basic test to see if you are iterating over an object or a hash map/associative array. It might even be a parameter in Link:
Code: (javascript) [Select]

var item = Link(this.damageTaken, { hash: true }).max(function(item) { return item.value; });
item.key // the answer you are looking for. Notice it's called key now.


Then when it searches this.damageTaken it knows it's a hash map and so 'recasts' it to a { key, value } pair and then continues the chain like before. This way you don't have to change the underlying data and it can iterate over arrays as well as objects.

Actually that may be quite neat. Picture using Link for certain hash maps:
Code: (javascript) [Select]

// updating health of all poisoned players in an associated array: ["Jim" = new Player(), "Bob" = new Player()];
Link(this.players, { hash: true }).pluck("value").has("status", "poison").invoke("hurt", 5, "green");

// or you can do this with a normal array:
Link(this.players).has("status", "poison").invoke("hurt", 5, "green");


It doesn't seem faster but in some situations it can be convenient. Sometimes storing players in a table like the above is a convenient way of keeping track of them and with Link you'll be able to iterate over it.

I'll give it some thought right now. My only concern is such a feature won't play nice with features that have a '.run()' method tied to them since they assume you iterate over an array and hence why they are so fast. I really want to redesign the library into a 0.3.0 version that isn't as bulky. I'll have to narrow down what I can get away with so I don't have to write so much repeated code. It'll likely only work in modern JS environments since I'd make use of newer JS features.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #171
This is why:

Code: (javascript) [Select]
HeadlessHorseAI.prototype.onUnitDamaged = function(unit, amount, tags, attacker)
{
if (unit === this.unit && attacker !== null) {
if (!(attacker.id in this.damageTaken)) {
this.damageTaken[attacker.id] = 0;
}
this.damageTaken[attacker.id] += amount;
}
};


If I set it up as an { id, value } table it would be much more work to update, since I would then have to search the table for an existing ID first, and then if it's not found add it.  Here I can almost do it in one step.
  • Last Edit: May 08, 2014, 01:26:30 am by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #172
The way I see it you either take the hit here or later on. It depends which gets called more frequently. Quite frankly I don't know what the trade-off is but I do know a for..in in JS can be notoriously slow. So while you do shave time having instant access to damages, you lose it all in the for..in. And without proper benchmarking there is no way to tell which is faster, but my money is on the purely array based approach. I have came to understand that a JS hash table is really best when not being enumerated. Otherwise arrays are great.

Then again you are hardly dealing with 100+ entries, so it shouldn't matter what you choose to use. :P
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #173
onUnitDamaged is called every time anyone in the battle takes damage (the table is updated only if the Horse is damaged however), while the search is done at most once per one of the Horse's turns--and in the case of the particular attack being targeted, it's not one that's used very often.
  • Last Edit: May 08, 2014, 09:17:51 am by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #174
So um, is Link:random() bugged, or am I doing something wrong?  I have the following query in one of my AIs:

Code: (javascript) [Select]
var combos = Link(Link(this.combos)
    .where(function(combo) { return combo.phase <= this.phase; }.bind(this))
    .sort(function(a, b) { return b.rating - a.rating }))
    .random(2);


The problem: After said query, combo[0] is a valid object, but combo[1] is undefined, leading to a game crash.  The length of the array is indeed 2, as expected.  I notice there's a splice call in Random(), could that be causing it?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #175
It could be. Random was carried over from the old query library and made for to run in link. I'll take a look at it when I get home. It is not a lazy implementation of a random function since its hard to go about grabbing a random element from an unknown sized list (due to potential filtering).
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #176
Ok, I fixed the random thing. But I wanted to add more optimizations and I was able to make the filterBy filtering 6 times faster, from 1.25 seconds to do an intense operation down to 0.20 seconds.

But it's tricky and you need to add some stuff to the query.

Code: (javascript) [Select]

// old way:
var items = Link(array).filterBy("property", value).toArray();

// new way:
function resolve(item) { return item.property  };
var items = Link(array).filterBy(value, resolve).toArray();


How is that faster? Resolving the property you want to filter against in an external function call is a bajillion times better for compilation than it resolving the property like so: item[property], behind the scenes.

Both methods will be accepted in the newer version of link, so you don't have to use the new way. It does take more code. And I want to further explore this so I could write less code.

I have already tried doing Function("a", "return a."+prop);, but it was too slow to construct the resolving function each time the chain was built (still pretty fast, but not faster than the old way).

Now... If I made Link with a schema attached to it... Something like:
Code: (javascript) [Select]

function schema() {
    this.prop = Number;
    this.prop2 = Boolean;
    // ...
}

Link(array, schema).filterBy(a, "prop").toArray();


I could use the schema to resolve the prop (somehow). But I'm not certain on the gains, but at least it will make making assumptions easier since all items in the array expect to implement that schema.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #177
I don't know, I have nothing against optimization in general, but I feel this is making low-level assumptions about the way the compiler works under the hood that could potentially, depending on the specific JS library used, change out from under you and end up making things slower.  Besides the fact that it makes the code more difficult to read--if I'm going to have to pass a function in anyway, I'd rather just go all-in and use a full filter() operation.  I see filterBy() as a convenience, and this takes all the convenience away.

What was wrong with random, by the way?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.12
Reply #178

I don't know, I have nothing against optimization in general, but I feel this is making low-level assumptions about the way the compiler works under the hood that could potentially, depending on the specific JS library used, change out from under you and end up making things slower.  Besides the fact that it makes the code more difficult to read--if I'm going to have to pass a function in anyway, I'd rather just go all-in and use a full filter() operation.  I see filterBy() as a convenience, and this takes all the convenience away.


I agree with you there, so I might scrap this new method if I can't make it intuitive enough. I am cheating the compiler (for chrome) by doing this, and it's technically not the best solution (though it is 6x faster). It always seems like more code = more speed, but at more inconvenience which Link tries not to do.

In IE this new method made it almost 7 times faster from 6.49 seconds to 0.86 seconds. But in Firefox it didn't make much of a difference (2x faster), huh. It seems FF has faster property lookup than IE and Chrome, IE being by far the worst.


What was wrong with random, by the way?


I never saw anything terribly wrong with it, but you can ask it to take more than one random item from the array and if that was greater than the array, extra undefined values get thrown in.
  • Last Edit: June 07, 2014, 05:36:07 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Link.js v0.2.12
Reply #179
If it's faster in all three of the major JS engines, I think you could say it's just faster as JS.