Monday, July 22, 2013

Local Reactivity in Meteor Web Applications

Every once in a while I stumble into something that changes the universe for me, allowing me rethink how I approach problems and develop solutions. Stumble because, while I can't necessarily plan on things like this happening, if I try to listen to people and keep my eyes open, I figure I'll eventually get lucky. When Meteor buzzed in a Cincinnati Javascript User Group meeting this Spring, I was happily surprised. And now just a few months later, it's become my new go-to web application framework.

Rather than try to introduce you to Meteor myself, I'll simply defer to the meteor web site www.meteor.com and let them do the talking. The site includes a high-level description of the framework, detailed documentation, example code and links to videos. The quality of the description and documentation alone merit your attention - and the capability of Meteor deserves your respect. This stuff is brilliant.

Of all the things Meteor brings to the table, Reactivity is the game changer for me. Updates to data sources cause dependent computations to be re-run, and the application shows updates immediately. The burden of carefully choreographing a dance between the server and the client to display pleasing changes in a timely way has been lifted. The dance is already beautiful and the performers are well-rehearsed. I can focus on building great user experience rather than on things like scratching my head over problems with data structures or working the weird bugs out of ajax callbacks.

Recently, when developing a web app I found myself wanting to use this strategy locally as well, building reactivity to be used only within a client. Though Meteor gives you session-level reactivity that propagates changes made to session variables locally, this wasn't quite what I wanted. Session variables are global to the client; I wanted variables that were at least scoped so I could keep them more closely associated with the functions and objects that use them. I've been conditioned to believe that global variables smell bad and I'm not ready to give up that sense yet.

Instead, I opted to adapt a notion that was mentioned in the Meteor documentation. I associated a variable and a dependency in an object and called it an injective. The idea is that I can inject client values into the reactive flow. In Coffeescript,

    Deps.injective = (init, options) ->
        _value: init ? 0
        _dep: new Deps.Dependency
        _force: !!(options && options.force) ? false
        set: (value) ->
            if (@_value != value) || @_force
                @_value = value
                @changed()
            @
        get: ->
            @depend()
            @_value
        depend: ->
            @_dep.depend()
            @
        changed: ->
            @_dep.changed()
            @
        force: (f) ->
            @_force = !!f
            @

The internal _value and _dep are managed through the get and set functions. Calling get returns the value while making the function asking for it dependent on the injective. Updating a value using set re-computes all functions that depend upon it.

A quick example perhaps, again in Coffeescript.

    App.innerWidth = Deps.injective window.innerWidth
    $(window).resize -> App.innerWidth.set window.innerWidth

This code creates an injective that tracks the inner width of the browser window. When the window resizes, the injective's value is set to the new inner width. While this might not sound like much, anything that has been computed based on the getting the value of innerwidth will be automatically recomputed when it changes. In the context of this example, that means that you don't have to know about the 23 layout decisions you made based on this value and how they'll need to propagate, and then manage it all yourself. Instead, you just grab the corner of the window and resize it, and watch the magic happen.

The depend and changed functions provide access to the dependency mechanism and are used by get and set. When depend is called, the injective adds the calling function to its list of dependents. An update to the injective using set will re-run these dependent functions. The changed function is what triggers the dependents to be re-run.

Finally, force is a way to force changes to objects and arrays values to be propagated without having to write any special comparitors. When the value being set is a scalar, == works: if the value is different it is copied and changed is called. If the value is an object (or an array) and the change is made within the object itself, == won't report the object has changed; a more complex comparison must be written to do the test. But that really isn't needed if you know about the complexity already. The force function (or constructor argument) provides a simple shortcut: if _force has been set to true then the set function trusts that the incoming value is different; set just goes ahead and updates the value and propagates the change. If something more complex is needed, values in the object can be adjusted and the injective's changed function can be called directly.

I've submitted injective (a Javascript version) to the meteor github repository. Maybe they'll integrate it, maybe not; I wasn't fixing a bug, just adding an enhancement so it doesn't have any sort of priority. However, it's a clean way to inject values into the reactivity stream that's useful for me. If it looks like it may be useful for you too, then enjoy!

Monday, January 14, 2013

Simple Drone Flying Algorithms

The AR Parrot Drone seems to be all the rage these days, especially here at the Neo Cincinnati office. Two officemates have drones, and they've taken to the office space and the hallways during lunchtime. The drone comes with piloting apps that control it in real time - but they can also be controlled programmatically. Work on drone drivers is progressing (one in Ruby, the other in Clojure) that can send commands to the drone.

A drome command is specified as a 5-tuple: (roll, pitch, yaw, altitude, duration) all relative to it's hover state. Once a command is complete, the drone returns to a hover state at its current location. From this it's relatively straightforward to make a drone fly in a simple pattern. Tilt and pitch define the forward direction, and yaw is used to change it.

To actually plan a pattern however, the command's values must be understood in relation to each other. Each is value specified in [-1, 1] in a drone command, and translated to an angle. Before programmed maneuvers can be created, scaling constants between angles must be determined. For example, consider flying one turn around a circle: the drone must be tilted forward (some combination of pitch and roll) and spun (a yaw value) over the time needed to complete a revolution.

(rc, pc, yc, 0, tc)

For a given tilt, spinning too fast spirals inward, while spinning too slow spirals outward. Too long or short a time will orbit more or less than one turn. Empirical studies of drone flight and timing must be done to determine these values. Assuming these values have been appropriately factored in then,

figurerollpitchyawaltitudedurationnotes
Circlerpy0tp&r = y
Spiral inrpy0tp&r < y
Spiral outrpy0tp&r > y
Figure 8rpy0tp&r = y
t = one revolution
rp-y0t
Tilted circlerpyatp&r = y
t = half revolution
rpy-at
3-leafed
Clover
rpy10t1p&r = y1
t1 = two-thirds revolution
t2 = half a revolution
00y20t2
rpy10t1
00y20t2
rpy10t1

Compound curves are defined as a series of simple pieces.

This is all fine, but to watch a drone move around a room in these sorts of algebraic patterns doesn't feel very aerobatic to me. The flying seems stunted and formulaic... more natural flight is a more complex dance of values. My best reference is a bird flying or fish swimming - when they maneuver, combinations of roll, pitch and yaw are smooth and complex. Changes in roll, pitch and yaw affect altitude. Coordinated moves are made to convert velocity into height. Soaring, diving, swooping - all feel like they should be aerobatic primitives.

Of course, these all will still be formulaic. But they'll look more natural. Somewhere in there is the beginning of the algebra of nature and what constitutes enough of this essence to feel birdish or fishish.

I'll be looking at this as our drones continue to learn to fly.

Monday, February 21, 2011

Laissez les bons temps rouler!

Starting on the day before Mardi Gras, I will be joining EdgeCase working in their Cincinnati office. To me, a much bigger party than they'll be having in the French Quarter!

This is a phenomenal opportunity, working alongside the genius of Jim Weirich and Scott Barron every day, and collocated with the Gaslight Software crew. (Let me tell you, this is a really smart room.)

Many thanks to Joe, Ken, Adam and Leon for taking the time to meet with me and make sure I'd fit there, and to everyone who's supporting me in this transition. To be sure, I'll miss the folks I've been working with, but I'm ready to get cracking on new stuff!

Sunday, February 14, 2010

Prototype and Witch's Brew

When things work differently in one part of a package than they do in another - for no apparently good reason - programming indigestion may occur. When you beat your head against the code for too long trying to figure out why things are screwing up, big headaches are sure to come. The cause of my current indigestion and headache? Element.insert in prototype.

I have some javascript code that renders a string containing some HTML to be added to the bottom of the contents of a some target element. I do the necessary incantation,

Element.insert('target',htmlString)

Which quite promptly does nothing. WTF?

It turns out that the htmlString I'm sending either needs a javascript toElement method defined that will convert it into a DOM object or it must be a DOM object already. The first alternative is unpalatable - I just want to create html, not a tree of DOM cruft. The second is just as bad, unless I can get the work done for me. Fortunately, I can.

In the body of my document, I declare a special, invisible div,

<div id="_cauldron_" style="display:none;"/>

and I use it to magically transform my html string into an object that I can insert into the target,

Element.update("_cauldron_",htmlString)
Element.insert(target,$("_cauldron_").firstChild)


The cauldron is where the html must brew to make the magic happen.

You may be asking, "Why does the conversion happen differently in the update? Why doesn't the insert work the same way?" Good question. I have no good answer though. To my way of thinking, The conversion should happen exactly the same way - otherwise kludges like this are forced. Suffice to say that it's all a moving target and everything's always changing. I'm sure this one will get fixed in a future Prototype release (or maybe it is already, my version is not the latest) but it does get frustrating.

Though the indigestion lingers, at least the headache is a little better now.

Tuesday, September 08, 2009

A little Hash goodness

Some quick refactoring this weekend had me throwing together some tidbits.
module Enumerable
  # return Hash of enumeration to yielded values
def collect_hash hash={}
inject(hash) {|h,e| h[e] = block_given? ? yield(e) : nil; h }
end

# return Hash of enumeration to non-nil yielded values
def select_hash hash={}, &block
collect_hash(hash,&block).compact
end

end


class Hash

# return Hash with nil values removed
def compact
delete_if {|k,v| !v }
end

# array-style push of key-values
def <<(hash={})
merge! hash
end

end
Yes, I know they've been done before, but they're quick one-liners and let me eliminate a lot of code. And as we all know, the easy code to maintain is the code you delete.