agentscript0
agentscript0 copied to clipboard
patch.agentsHere() -> getter?
Looks like patch.agentsHere() wraps patch.agents, making sure it's populated before returning a value. Would it make sense to replace this with a getter?
Yup. It looks like getter/setters work reasonably well and performant as I recall.
Then we could move away from foo() methods and just have .foo properties. There may be exceptions, naturally, but properties sure make sense.
On Thu, Oct 30, 2014 at 5:09 PM, Benny Lichtner [email protected] wrote:
Looks like patch.agentsHere() wraps patch.agents, making sure it's populated before returning a value. Would it make sense to replace this with a getter?
— Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67.
Another reason why getters/setters might be nice--if you set an agent's x/y coord without using setXY(), patches don't update their agentsHere property.
I thought that creating getters and setters was slow, but this test shows that I was wrong http://jsperf.com/es5-getters-setters-versus-getter-setter-methods/14 . Their performance also seems good http://jsperf.com/es5-getters-setters-versus-getter-setter-methods/13
Cody Smith
On Wed, Nov 5, 2014 at 5:36 PM, Benny Lichtner [email protected] wrote:
Another reason why getters/setters might be nice--if you set an agent's x/y coord without using setXY(), patches don't update their agentsHere property.
— Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67#issuecomment-61908643 .
The issue for me is when to use them and how.
So for example, if I have a property "color" that when I set it, I have a side effect. It has to do something like turn the color into a pixel, say or possibly set a "dirty" bit. I don't want to use _color to do so, I just want side effects .
I think setters/getters are fine for that as well, right?
Another example is setting a compound value, [x,y] say. Inside my obj I probably want obj.x and obj.y. So a "setXY(x,y)" makes sense, especially if they actually have a side effect that uses both x and y. In AS, for example, setting an agent's x,y also puts it in a cache inside a patch for "agentsHere". But I prefer property setting everywhere possible, so obj.position = [x,y] would be cool. On the other hand, if that sets obj.x and obj.y, it will have a lot of GC overhead, tossing the arrays every use.
So would we set position via getters/setters? Especially when they're agents that move each "tick"?
I have to confess to despising _foo too .. it does not express intent for me.
On Thu, Nov 6, 2014 at 10:36 AM, m0ose [email protected] wrote:
I thought that creating getters and setters was slow, but this test shows that I was wrong http://jsperf.com/es5-getters-setters-versus-getter-setter-methods/14 . Their performance also seems good http://jsperf.com/es5-getters-setters-versus-getter-setter-methods/13
Cody Smith
On Wed, Nov 5, 2014 at 5:36 PM, Benny Lichtner [email protected] wrote:
Another reason why getters/setters might be nice--if you set an agent's x/y coord without using setXY(), patches don't update their agentsHere property.
— Reply to this email directly or view it on GitHub < https://github.com/backspaces/agentscript/issues/67#issuecomment-61908643>
.
— Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67#issuecomment-62018700 .
Can you send link about expressing intent. Was that in Vlad's talk? On Nov 6, 2014 11:06 AM, "backspaces" [email protected] wrote:
The issue for me is when to use them and how.
So for example, if I have a property "color" that when I set it, I have a side effect. It has to do something like turn the color into a pixel, say or possibly set a "dirty" bit. I don't want to use _color to do so, I just want side effects .
I think setters/getters are fine for that as well, right?
Another example is setting a compound value, [x,y] say. Inside my obj I probably want obj.x and obj.y. So a "setXY(x,y)" makes sense, especially if they actually have a side effect that uses both x and y. In AS, for example, setting an agent's x,y also puts it in a cache inside a patch for "agentsHere". But I prefer property setting everywhere possible, so obj.position = [x,y] would be cool. On the other hand, if that sets obj.x and obj.y, it will have a lot of GC overhead, tossing the arrays every use.
So would we set position via getters/setters? Especially when they're agents that move each "tick"?
I have to confess to despising _foo too .. it does not express intent for me.
On Thu, Nov 6, 2014 at 10:36 AM, m0ose [email protected] wrote:
I thought that creating getters and setters was slow, but this test shows that I was wrong http://jsperf.com/es5-getters-setters-versus-getter-setter-methods/14 . Their performance also seems good http://jsperf.com/es5-getters-setters-versus-getter-setter-methods/13
Cody Smith
On Wed, Nov 5, 2014 at 5:36 PM, Benny Lichtner [email protected]
wrote:
Another reason why getters/setters might be nice--if you set an agent's x/y coord without using setXY(), patches don't update their agentsHere property.
Reply to this email directly or view it on GitHub <
https://github.com/backspaces/agentscript/issues/67#issuecomment-61908643>
.
Reply to this email directly or view it on GitHub < https://github.com/backspaces/agentscript/issues/67#issuecomment-62018700>
.
Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67#issuecomment-62023256 .
On Wed, Nov 5, 2014 at 5:36 PM, Benny Lichtner [email protected] wrote:
Another reason why getters/setters might be nice--if you set an agent's x/y coord without using setXY(), patches don't update their agentsHere property.
But don't you want them to? I.e. when an agent moves, it removes itself from its current patch cache and moves it to the next one. We have a stunt to not cache for models not needing it, but I think many models refer to their patch: a.p.n4 for example.
What would the getter/setter look like? agent.position = [x,y]? Would that require a allocate/GC of that array? Not sure how good JITs are at local fast GC.
However, there's a nifty stunt we could use. I'm looking into how to make the patches more OofA-ish. The patches are layed out from top/left to bottom right. If I remove x,y from patches and replace their location by their id (=== array index), we remove both x & y from each patch, saving around 16 bytes each.
Convert from using the x,y and deriving x,y from i, saves 12,582,912 bytes .. around 12.6MB in a 1024x768 model, Stephen's standard, and the computation is pretty fast. It might be worth the trade-off
The issue then becomes how visible we make this stunt. Patches currently support patchIndex(x,y). We could just use this as the standard patch accessor, with a deprecated x,y accessor like we currently do with patchXY(x,y)
On Wed, Nov 5, 2014 at 5:36 PM, Benny Lichtner [email protected] wrote:
Another reason why getters/setters might be nice--if you set an agent's x/y coord without using setXY(), patches don't update their agentsHere property.
— Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67#issuecomment-61908643 .
On Thu, Nov 6, 2014 at 11:10 AM, Stephen Guerin [email protected] wrote:
Can you send link about expressing intent. Was that in Vlad's talk?
No it was in the talk by the Traceur team lead.
See Erik Arvidsson below
---------- Forwarded message ---------- From: Owen Densmore [email protected] Date: Fri, Oct 31, 2014 at 8:55 AM Subject: Re: interesting that leaflet went the other way, from mixin -> subclass for events To: Benny Lichtner [email protected]
Great find! I definitely am a Vlad fan. Did you look at his keynote I sent out a while back? I'm starting a list of "simplicity patterns". http://en.wikipedia.org/wiki/Convention_over_configuration is one of them. Note use of defaults, a core idea in NL/AS.
Lets try to chat today, hangout or mail.
I have to agree that mixins are best used only for functions, and be free of associated data variables, or possibly use convention for the names of the variables they manage (color, x, y, name etc).
I also just watched a talk: ES6 in Angular 2.0 by Erik Arvidsson at ng-europe 2014 https://www.youtube.com/watch?v=iij5RHKi66o .. and was impressed that he wasn't shy about classes. See tweet below.
And after looking at the http://agentscript.org/sketches/noanim.html sketch, I would like to have event capabilities, even replacing the animator .. i.e. run on mouse moves, object changes, and so on.
I'm not clear on where the evented code would live. Would it be a stand-alone class that model would use as an alternative to or addition to animator? The noanim sketch certainly is slick, using @once() in Model whenever any change occurs. I think this will be the stunt we use to get Stephen's IDE.
I'm interested in more detail in how you use it in simtable etc. It looks to me to be core. The only issue is how/where it lives in the model world. Animator is currently a has-a within Model. Maybe Evented is an alternative to that?
-- Owen
Owen Densmore @backspaces https://twitter.com/backspaces 12h12 hours ago https://twitter.com/backspaces/status/528012527699906560
Nice talk: es6 features & how they change es5 code; how use Traceur for own language features & AtScript Angular DSL https://www. youtube.com/watch?v=iij5RHKi66o … https://t.co/6yy2Ea6bfQ
Another reason why getters/setters might be nice--if you set an agent's > x/y coord without using setXY(), patches don't update their agentsHere property.
But don't you want them to?
Err, yes. Here's what happened: Carolyn and I were working on making agents draggable. We did something like this:
agents.on 'drag', (e) ->
agent = e.target
agent.x = e.patchX
agent.y = e.patchY
But this had a bug: the dragged agent didn't update its new patch.agentsHere prop. Instead we needed to do:
agents.on 'drag', (e) ->
agent = e.target
agent.setXY(e.patchX, e.patchY)
I think modelers shouldn't have to worry about the difference between these two versions. There shouldn't even be two ways to update an agent's position.
Kinda tardy, but I've been learning a lot about getter/setters and proto inheritance lately.
For colors, I've used defineProperties to make easy access to functions that live behind them. Works fine for setting single properties but for compound properties (arrays, objects) it seem you have to pass in objects/arrays that are generally GCed, and have lousy performance is called a lot. (I've used both jsperf and Chrome's timers .. the latter I believe enforces GC at the end timer)
The particular instance that bit me was in TypedColor. It has a single function, setColor(r,g,b,a=255). So in using the property approach, I found myself using an array: color.rgba = [r,g,b] or [r,g,b,a](handling the a=255 default).
Works fine BUT has pretty hight GC overhead for setting the colors of a lot of objects.
This could be solved in several ways
- Have individual r,g,b,a object properties, but that's pretty ugly..
- Keep the array, storing it in a color.rgba variable. That failed because the color itself is an typed array for r,g,b,a with a pixelArray property that uses the same typed array buffer. So no matter how you do it, you run into GC issues that are pretty expensive.
Note This didn't even take into account things like setting x,y does other things (quad tree, pushing the agent into a patch cache)
My solution was to simply document the possible performance problem, and provide the core color.setColor method which is equivalent to the color.rgba = [r,g,b]. It only takes up one extra prototype entry, and thus is quite inexpensive .. i.e. it does not add more to the "instance".
In the x/y case, the same occurs: they really do come in pairs. So you could move away from ins.x & ins.y and have an ins.pt which is either an array or object. It does has the advantage of being more 3D ready, with a z value defaulted to 0, say.
There would still be an inescapable GC event for every use of the ins.pt = [2,4], either keeping the new one and tossing (GC) the prior pt, or setting the existing pt, and GCing the [2,4] when done with it.
So I've for the while settled on both: the more elegant property, and a function that lies behind it for direct use. Basically functions don't GC their args, they're in a stack.
And naturally, pre-built, static instances help a lot, hence the colormaps.
-- Owen
On Thu, Nov 6, 2014 at 10:40 PM, Benny Lichtner [email protected] wrote:
Another reason why getters/setters might be nice--if you set an agent's > x/y coord without using setXY(), patches don't update their agentsHere property.
But don't you want them to?
Err, yes. Here's what happened: Carolyn and I were working on making agents draggable. We did something like this:
agents.on 'drag', (e) -> agent = e.target agent.x = e.patchX agent.y = e.patchY
But this had a bug: the dragged agent didn't update its new patch.agentsHere prop. Instead we needed to do:
agents.on 'drag', (e) -> agent = e.target agent.setXY(e.patchX, e.patchY)
I think modelers shouldn't have to worry about the difference between these two versions. There shouldn't even be two ways to update an agent's position.
— Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67#issuecomment-62098898 .
Thanks, Owen! It's nice to have this summary of your research.
For x,y, would it be so terrible to duplicate the update logic? Right now Agent.setXY() includes the following to update its patch's list of agents:
@p = @model.patches.patch @x, @y
if p.agents? and p isnt @p # @model.patches.cacheAgentsHere
u.removeItem p.agents, @
@p.agents.push @
Would it be bad news bears to put that in the setter for x, as well as in the setter for y?
I am interested in what the conclusion to Benny's question about getters/setters for x and y was?
First of all: getters/setters seem to be pretty nice, so I'm certainly open to their use. It wouldn't be hard to add for x,y, just defineProperty .. but I think it only makes sense to add both x,y at the same time, which would be an array [x,y] for the setter & getter.
Secondly, we use cloneClass & cloneObject functions in the utility module. They unfortunately failed, they didn't do the right thing for setter/getters .. they set the setter/getter name to the property at the time of the clone .. not the get/set functions.
But yay! I found a solution using the more modern Object.foo static methods, like I sent out today.
So the bottom line, I think we can use get/set .. which will be way nicer in es6 .. but it needs a bit of testing and use to be sure.
They'll get a lot of use in my color integration strategy, so stay tuned. If it works, we can basically use get/set anywhere we need side effects rather than just setting a property.
-- Owen
On Wed, Feb 18, 2015 at 11:32 AM, m0ose [email protected] wrote:
I am interested in what the conclusion to Benny's question about getters/setters for x and y was?
— Reply to this email directly or view it on GitHub https://github.com/backspaces/agentscript/issues/67#issuecomment-74919575 .
Cody, are you referring to this question?
Would it be bad news bears to put that in the setter for x, as well as in the setter for y?
I think we decided offline it was too much overhead to edit two patch.agents arrays every time you want to update an agent's position.
Still looks like patch.agentsHere() could be replaced with a getter though (maybe rename the patch.agents array to patch.agentsHere).
Well, to be clear we could use both a getter and a setter (the setter of which calls the setXY method), but using arrays as the "value". This makes sense, you're setting a x,y position. So the getter/setter would most reasonably use an [x,y] array. IIRC x,y are properties, that can be gotten easily enough individually, just not set directly due to side effects.
So "sugaring" places where functions (side effects) are called seems fine to me, and maybe JS GC will eventually be clever to treat such arrays as local stacks or at least immediate GC'd.
The GC issue is that when the step function moves an agent, it can easily call a setXY a million times, so calling the function is likely more efficient. On the other hand, in less extreme cases, the GC may not be an issue.
I'm now less interested in using a getter/setter for x and y. Since the setting needs to happen with both coords simultaneously anyway, I don't see any disadvantage to sticking with setXY as is. Switching from x and y to a single position attribute seems like more trouble than it's worth in this case.