picture home | pixelblog | qt_tools

omino code blog

We need code. Lots of code.
entries for category "code"
David Van Brink // Thu 2014.04.10 13:17 // {broad generalities code}

Code Connectivity

Thought of the moment.

There are levels of interconnectedness…
Level 1 — basic — compiler knows they are the same. Command-click or F12 finds it…
Level 2 — intermediate — strings match. grep -r can find it…
Level 3 — majikal — you have to know something about some rules for construction…
Level 4 — arcane — you just have to know.

It’s nice to hover around Level 1 or Level 2.
If you’re in Level 3 or Level 4, maintenance is… challenging. But can be slightly mitigated if you can create a unit test or build step that, somehow, confirms that everything is lining up.

oh, i dont know. what do you think?


David Van Brink // Sun 2013.12.29 10:14 // {code ios}

iOS: Multiple Screens Oddity

Presently working on a little iOS app for some theatre related work. Wanted to display some information on a secondary screen. The iPhone supports this nicely, with either an HDMI adapter, or a composite video adapter, or AirPlay to an Apple TV.

Apple has an example project which shows this, and works well: https://developer.apple.com/library/ios/samplecode/ExternalDisplay/Listings/ReadMe_txt.html

Gotcha Number One
On my iPhone, the sample app works fine. I can enable and disable AirPlay, or plug and unplug the HDMI adapter, and the app rolls with it. But on iOS Simulator 7.0, using the Hardware:TV Out menu to do that virtually (TV Out disabled/enabled) causes the app to crash. So no testing there!

Gotcha Number Two
What is rarely mentioned, and I’ve only discerned by innuendo, is that your AppDelegate must expose a property for each UIWindow you create. The default generated AppDelegate always includes .window. And if you use a Storyboard Nib, then it’s all magicked for you.

So anyway, you need to have this in your AppDelegate.h:

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIWindow *secondWindow;

The example project calls the second one extWindow.
And the idea is mentioned, in passing, in this apple note.

An iOS developer offers some tips (but not this one!) at this entry.

So many secrets!

oh, i dont know. what do you think?


David Van Brink // Sat 2011.11.5 10:10 // {code java}

Threads

Aah, threads, so beautiful and so dangerous.

In this note, I’ll jot down a couple of recently-encountered threading hazards, for future reference. Perhaps this post will evolve into a Basics note at some point.

My context for now is Java, but the concepts are somewhat general.

Life Before Threads

I got my start doing programming on an Autonetics Recomp III. My Junior High School teacher Elliot Myron had one of these even-then-antiques as a hobby. And a dozen paper tape punches where we hand-entered octal assembly programs to run. No interrupts! And so, no threads.

Later, I wrote a few Apple II video games. These incorporated 1-bit sound effects and animation and multiple agents acting simultaneously… again, no interrupts, and no threads.

Lately, I occasionally program 30-cent PIC chips to blink light patterns and such. Yeah, you got it, no interrupts, no threads.

So it turns out you can (and probably should) do all sorts of interesting things without lots of threads. Modern programming is rather far removed from the lowly “interrupt” and I’ll refrain from mentioning again… but interrupts is where threads come from. Mostly.

Clotho

First red-flag: If you find yourself starting a sentence with, “And there’s one thread per…” just stop right there. Do not have one thread per player, or one thread per incoming request, or one thread per anything.

Lachesis

Second red-flag: When you do your locks within a class, some say, “Lock on the most local object you can.” I found this lead to confusion. I found it far safer to do all locks on “this”, just to keep it consistent. By all means, hold them as briefly as possible.

By locking always on the same thing (this) it eliminates the possibility of out-of-order lock and unlock.

Consider locking and unlocking inside a loop instead of outside it. Although I’ve found cases where unlocking made things slower, as more task switching occurred overall.

Atropos

Lastly, here’s the least-obvious and possibly most-important. If you’re managing handlers and callbacks… release the lock before calling your client’s callback code. Do your work, set your safe copies and state, and then release the lock and call them.

You see, they’re likely to make calls back into the library which then have more locks. In a messaging system, they’ll send messages on another queue which also has locks. Avoid deadlock by letting their code run free.

Sounds Awful

It is, it is. A really great article about some really, really smart people trying to use threads is here.

The best thing to do is, Don’t use threads. Browser-page JavaScript and server-side node.js both run in a single-thread style. Emulate that as much as possible.

Of course, to emulate that you need to write some thread-hiding layers. Hence, the above advice.

Carry on!

oh, i dont know. what do you think?


David Van Brink // Sat 2011.07.30 13:04 // {code software architecture}

HTTP “Comet” Realtime Messages

What you Want

For some web applications, you want to send realtime messages between the browser and the server. That is, the browser can send a message to the server at any time (this is typical), and the server can send a message to your session at any time, too (this is not what HTTP was designed for!)

What you want: to send a free immediately-delivered message any time you want.

What you get: they’re not free, and they may be far from immediate.

This note will describe a cargo trucking analogy for HTTP requests, and expand on it for interactive (“Comet”) style use.

Truck4
Let’s look at a couple of typical browser use models.

You see a link, you click on it, and the page comes up.

==> You send an empty truck to the factory, and it comes back with a load of standardized cargo.

You fill out a small form, press “Submit”, and some page comes up.

==> You send a lightly-loaded truck out. It has some instructions on a clipboard. At the factory, they read your clipboard, load up the truck, and send it home.

You upload a photo using a web-based form. A page comes saying, “Your photo is up, click HERE to see it.”

==> You send out a loaded truck, it comes back empty with a note saying, “We got your photo.”

These are all one-time events, initiated by you at the browser. The HTTP request/response model works pretty well for this. Let’s look at one more typical use case.

You’re very concerned about, let’s just say, the temperature in Fahrenheit at the Town Hall Weather Station. So every 5 seconds you click the refresh button. Refresh, refresh, refresh. And every 5 seconds, the empty truck rolls out, and returns with more or less the same cargo. Every few minutes, perhaps, the temperature changes and a different cargo comes back.

Truck6

Interactive Communication

Let’s call the browser “you” and the server “the factory”. Here’s what we have so far:

  • You have an infinite supply of trucks.
  • You can send a truck to the factory any time you want.
  • You can choose what to put in the truck on the outbound trip.
  • The factory chooses what to load into the truck for the return trip.
  • The factory has no trucks unless you send one.

From here out, we’ll mix the metaphors and pretend not to notice.

Consider a chat session between you and a server-based robot. Let’s assume that it’s quite thoughtful and conversational, and doesn’t merely immediately reply to each thing you type. Rather, it might consider your words for a time, or even have something to blurt out on its own.

Here’s several possible implementations. Here, the truck is a Mail Truck, but that’s not important.

Single Truck Stays Home

Every time you type a message and press return, the truck goes out with your message, drops it off and immediately comes home. If there were any messages waiting for you, it picks them up.

Good: Acts just like a web request, nothing happens unless you hit return.

Bad: The robot never gets to tell you anything, unless you speak first. You end up typing “hello?” a lot.

Single Truck Waits For Reply

When you press return, the truck heads to the factory with your message. Then, it waits there until the robot has something to say. When it does, it comes back with the robot’s message. Meanwhile, you couldn’t say anything. You didn’t have the truck.

Good: Sometimes the robot can speak immediately, and sometimes you can.

Bad: Sometimes you cannot say anything, because you have no truck, and sometimes the robot can’t, for the same reason.

Single Truck Goes Back And Forth Always All The Time

Let’s say that every 5 seconds, the truck heads out with anything you’ve said in that interval, and comes back immediately with anything the robot has said. Now we are talking!

Good: Looks just like a regular web request. Messages are delivered more or less regularly. Things are looking up.

Bad: The truck is always making the trip, even when there’s no cargo. And the deliveries are never immediate.

Intermission

Truck1

You noticed we introduced a new concept: That of the truck waiting at the factory. That’s allowed! (Up to a point; if it takes too long you must assume the truck has been lost.)

This idea of the server holding on to the request for a little while is referred to as “Comet”, a play on “Ajax”, which comes from “asynchronous javascript and xml”.

Anyway, now we’re getting somewhere. A few more items:

  • Every time the truck rolls, it has a cost. Sending a truck home empty is wasteful.
  • Leaving trucks at the factory for a time has some cost.
  • It’s legal for a browser to open a TCP connection, send a request and get the response, and then close the TCP connection. Alternatively, it can keep the TCP connection open and use it again. Requests can be pipelined, and responses will arrive in order. Oops, trucks, right…
  • Sometimes you destroy a truck as soon as it returns, and sometimes you keep it around. Which is more expensive depends on how long you’re keeping it parked.

Multitruck Solutions

Forget about the chatty robot. You get the idea by now.

Expanding Fleet of Trucks

You start by sending a truck to the factory, just in case. Then if you need to send something, you send another truck to the factory. It stays there. Sending a truck home empty, you see, is wasteful. If trucks are free, we can leave them for use at the factory as needed.

When the factory needs to send something home, it’s got at least one truck ready. If it ever runs down to none, we’ll send it an empty one again.

Good: We’ve minimized the road-time of empty trucks.

Bad: The factory has limited parking, and we’re actually not the only customer. Trucks may get old and rusty sitting at the factory disused. (Or rather, they’ll get towed, slapped with a Timeout, and we may have to send out a fresh one.)

Fleet of Two Trucks, Variation One

We keep one empty truck at home, and one at the factory. We can send our truck over at any time, and it gets sent home immediately, empty. If the factory has something to send, it has a truck and uses it. We immediately send it back to the factory, empty.

Good: Now, we’ve both got trucks, except for very brief times right after we’ve sent something.

Bad: The factory-based truck runs a big risk of parking tickets, while the home-based truck doesn’t. Also, half the truck trips are empty, after all, alas!

Fleet of Two Trucks, Variation Two

We start by sending an empty truck to the factory. If either we, or the factory, need to send something, we use the truck that’s there. Whenever a truck arrives, we send out the other one. (If we both sent at the same time, then, hooray, we just use the truck that rolls in.)

If a parking ticket is imminent at the factory, we send it home empty, and the other truck arrives in its place.

Good: We can both send any time. If either of us send, we reset the parking-ticket time.

Bad: On average, half the truck trips are empty.

Observations

To recap, the algorithms described were:

  • Single Truck Stays Home
  • Single Truck Waits For Reply
  • Polling: Single Truck Goes Back And Forth Always All The Time
  • Many Requests: Expanding Fleet
  • A Slow Request and a Fast Request: Fleet of Two Trucks, Variation One
  • Ping-pong Requests: Fleet of Two Trucks, Variation Two

The first two are just broken. They don’t let communication readily occur.

The other four are all viable, with different kinds of costs.

Polling is nice and easy to understand. It puts a fixed upper bound on the latency of your messages, and an average latency of half that. But it sends a lot of empty trucks; lowering the rate of trucks increases the latency.

Using Many Requests keeps a lot of open connections, but minimizes empty trucks. It also contradicts the HTTP 1.1 RFC, section 8.1.4, which says you SHOULD NOT have more than two trucks out.

A Slow Request and a Fast Request is ok. (If you’re accustomed to web queries, it may “feel” nice because the home-based truck seems to associate requests and responses, but this is fallacious. If we’re really passing asynchronous messages, then the message protocol defines the request/response associations, not the HTTP protocol.)

Ping Pong Requests seems to be the nicest of the bunch. It’s a slight improvement over the Slow and Fast Request method, in that the server may have more chances to avoid a timeout on the waiting request. Its symmetry is perhaps slightly appealing as well.

Caveats and Conclusions

Me? I’ve never done any of these. Working through it now, have some prototypes up and running based on JavaScript client, and Restlet-based Java server. But the truck analogy has proven useful in contemplating these algorithms. I’m leaning towards Ping Pong, and plain old Polling as the two most viable modes.

Truck3

References

HTTP 1.1 specification RFC 2616, see Chapter 8 on “Connections”.

oh, i dont know. what do you think?


David Van Brink // Sun 2008.09.14 18:45 // {code scripting wordpress}

simple browser tricks

In a detour to a detour to some longer term goal, I needed to do some minimal HTML/JavaScript coding. The regularly scheduled hardware and WBL tinkering — including soldering, LEDs, and wireless sensors — will resume shortly.

++more

oh, i dont know. what do you think?


David Van Brink // Thu 2008.06.12 09:17 // {broad generalities code}

Code Velocity Profile

  1. A body of code is never finished
  2. The authors have in mind some “next steps”
  3. The code implicitly supports these particular next steps, and similar ones
  4. The code implicitly hinders wildly different next steps
  5. Adoption by users implicitly supports the current state and, depending on apparent paradigm, supports the intended next steps
  6. Adoption by users resulting in persistent manifestations of the current state — that is, saved documents — explicitly hinders wildly different next steps
  7. Intermittent development may distract from those next steps, but they are still implied by the code (and the current state is required by extant persistent documents)
  8. Development by new authors may distract from those next step, but they are still implied by the code (and the current state is required by extant persistent documents)
  9. If you accelerate for six months towards the wrong star, it takes 18 months to turn your spaceship around, decelerate, and return to your starting point at a stop. Less if you don’t mind overshooting.

Seems about right.

Compelling charts and graphs omitted.

oh, i dont know. what do you think?


David Van Brink // Tue 2008.05.27 16:46 // {code java}

Java Gotcha

I was working on some code, and finding that it broke a bunch of unit tests. By the advanced method of “commenting out the new stuff”, I found that the line in red below appeared to be causing the problem.

If I commented out the line in red, everything worked! Put it back in, it all breaks!

for(IDocumentUrl doc : docs)
{
	@SuppressWarnings("unused") AltNode docUrlNode = new AltNode(DOCUMENT_URL);
//	docUrlNode.setValue(DISPLAY_NAME,doc.getTitle());
//	docUrlNode.setValue(TYPE,doc.getType().name());
//	docUrlNode.setValue(URL,doc.getUrl());
//	cardNode.addChild(docUrlNode);
}

What’s the deal?

The line in red is just allocating a harmless object. In fact… I replaced it with:

for(IDocumentUrl doc : docs)
{
	@SuppressWarnings("unused") Integer x = 3;
}

With the same symptoms. Comment out the line in red, and all is well.

Ah. Java does do some optimization! Removing the contents of the iterator loop allowed Java to omit the entire loop. Turns out docs was null; removing the contents of the iterator loop avoided an exception.

All fixed:

if(docs != null)
  for(IDocumentUrl doc : docs)
  {
    @SuppressWarnings("unused") AltNode docUrlNode = new AltNode(DOCUMENT_URL);
    docUrlNode.setValue(DISPLAY_NAME,doc.getTitle());
    docUrlNode.setValue(TYPE,doc.getType().name());
    docUrlNode.setValue(URL,doc.getUrl());
    cardNode.addChild(docUrlNode);
  }
oh, i dont know. what do you think?


David Van Brink // Sun 2008.03.23 20:54 // {c code wbl weird blinking lights}

Retro USB MIDI Device VI

First Working Code

After much tinkering and poring over data dumps and specs, I have flashed the PICDEM FS USB board such that, when plugged into the Mac, it shows up as a usable MIDI input. (Doesn’t yet show up properly on Windows XP, though.) This, using a Pic 18F4550.

From reading and googling the subject, it seems that most USB developers start by creating the descriptors, and committing them to ROM.

I took a different approach. I wanted to have a flexible and repeatable way to create new MIDI devices as needed. Who knows, I might do more than one. And this way others might benefit from it too, potentially. As part of main, I call a setup method which dynamically creates the all the descriptors, strings, & so on. I donated 256 bytes of RAM (out of 2k) to hold the descriptors. And the code to poke it all in chews up a K or so of program space. But, for now at least, the freewheeling flexibility is worth it.

    UsbMidiSetup(0x0832,0x401c,5,5,
        "omino.com products",
        "omino 8038 controller"
        );

The above C call creates in memory the device and configuration descriptors for a Streaming Audio (MIDI) USB device with Vendor ID 0832, Product ID 401C, five MIDI input cables, five MIDI output cables, for a company named “omino.com products”. It shows up in the MIDI patchbay as an “omino 8038 controller”.

Below the cut, some trivia about the Pic 18F4550, the PICDEM FS USB demo board, and their development tools.

++more

oh, i dont know. what do you think?


David Van Brink // Mon 2007.12.17 10:13 // {broad generalities code}

Dear Plugin Developer

Dear Plugin Developer,

Always code defensively. Assume the rest of the system is insane, and your module a small island of clarity, nay, robustness, in a sea of unreason.

We do NOT guarantee to call any interfaces or API methods in any particular order. We do NOT guarantee even to set only legal parameters! (This is because “we” are not always GooEdit, “we” are scripting clients, other editing hosts, anyone with a compiler might eventually call your plugin, joining the ranks of “we” to your “they”.)

On the flip side, we bulletproof GooEdit against plugins throwing exceptions, returning absurd results, and so on.

So!

The interface you were asking about is ISetMoreInfo. And sometimes the value will be “null”.

–> Goo

oh, i dont know. what do you think?


David Van Brink // Fri 2007.10.26 18:32 // {broad generalities code}

Basics: Write Short

Code comments and email subject lines should be as short as possible, and no shorter. They don’t have to be full-featured English.

Basics: Write Short

In writing, brevity is a virtue. Samuel Clemens, responding to one particular excess, wrote: “Substitute ‘damn’ every time you’re inclined to write ‘very’; your editor will delete it and the writing will be just as it should be.” There appears to be a misperception that great meaning requires lengthy prose; but to misuse Yoda’s words: “Size matters not.”

The title of this post was “How to write short”, then “Please write short”, and, finally, “Write Short”. Brevity is of especial importance in code. Other contexts of critical brevity include:

  • code comments
  • email and bug-report subject lines
  • blog posts

Code: Get Rid of Of, and And, and To, Too

(I’ve noted some of the patterns, but I suspect my nomenclature is flawed. Improvements welcome.)

nameOfPort should be portName (noun aspect pattern)

getNumberOfFish() should be getFishCount() (verb aspect noun pattern)

saveIfNecessary() can be maybeSave() (adv verb pattern, & your reader can trust you)

addFishToPond() should be addPondFish() (verb dest source pattern)

And my favorite: the_address_line_to_the_uart1 should be uart1_address (noun aspect pattern)

Code Comments: What, Not How

There’s plenty of available wisdom on comments; a veritable commentary of commentaries on the subject, even. I’ll offer just one example of comment shortness.

// set n to the number of fish

should be

// n is the fish count

How it happens is the code; what has happened may be worth a comment.

Email & Bug Report Subject Lines: Frontloaded Please

The important thing to remember is that email and bug report lists often appear in tabular form, with the Subject column truncated. Keep it short, and lead with the most important words.

Help!!! I opened the document and then selected the first block and it froze!

Should be…

Freeze after Open & Select-Block

And that’s enough of that. On to our last area of brevity…

Blog Posts…

Guilty, but I’ll try harder. Bye now.

oh, i dont know. what do you think?



(c) 2003-2011 omino.com / contact poly@omino.com