The Shape of Everything
A website mostly about Mac stuff, written by Gus Mueller
» Acorn
» Retrobatch
» Twitter
» Mastodon
» Instagram
» Github
» Maybe Pizza?
» Archives
» Feed
» Micro feed
November 28, 2018

Dominik Wagner: SubEthaEdit 5 – Now free and open source!

It's story time.

Way back in 2003, when SubEthaEdit was still called Hydra, it won a round of the Mac OS X Innovators Contest from O'Reilly. My app at the time, VoodooPad (now owned by Primate Labs), also won a place in the contest. Audio Hijack Pro also made an appearance as a runner up to VoodooPad.

Because of international and political reasons, VoodooPad got first place with an award of a premier level membership to Apple's developer program. This was a pretty big deal! The regular membership cost $500 a year, but it came with a 20% discount on hardware which usually made up for the cost.

The premier membership was $3500, but it came with a pass to WWDC along with 10 hardware discounts. Ten! And a pass to WWDC!

My company was just me, so I only needed one hardware discount. But back in the day, indies helped indies and the hardware discounts were transferable, and I did what was the completely obvious thing to do.

So I sent a couple of the hardware discounts to the folks at Rogue Amoeba (makers of Audio Hijack) and the folks at the Coding Monkeys (who made SubEthaEdit). We were all pretty happy.

Then a few days later I got a call for ADC. "What the heck are you doing?" they asked. I said that I didn't need that many and gave a couple of discounts to them. "Are they doing work for you or something? Because the Coding Monkeys have a student ADC account, and it's not possible for them to have a hardware discounts and we're going to transfer those back to you."

Well crap. OK.

"And what about Rogue Amoeba?". Well, uh- yes. They are doing work for me. Yep. They sure are. Sub-contracting, it's completely official. Long pause. "OK."

To be fair, Paul Kafasis from Rogue Amoeba was helping me out a lot. Even though he's about 10 years my junior, he had been doing indie software development for a bit longer at the time and as far as I was concerned, was also quite a bit wiser about the whole business end of it. I got lots of good advice, and his company got some hardware discounts.

Anyway, that's my SubEthaEdit story. They eventually won an ADA as well, which I'd rather have than 100 hardware discounts.

Multiple Return Values in JavaScript

Luciano Mammino: Emerging JavaScript pattern: multiple return values.

You probably know already that JavaScript does not support multiple return values natively, so this article will actually explore some ways to “simulate” this behavior.

There are some neat ideas in here enabled by features from ES2015 which made no sense to me at the time, which suddenly do now.

Indexed PNGs in the Latest Builds

Both Acorn and Retrobatch are getting the ability to create indexed PNGs in their next releases (versions 6.3 & 1.1.1). This is the elusive "8 bit" PNG file (or even less if you'd like it). PNG images can be crunched to as small as 10% of the original size, it's pretty amazing. Try them out on the latest builds page.

FastMail Is Kind of Awesome

I recently switched servers for Flying Meat (to Linode), and as part of that I also switched to using a hosted mail server. I'd been trying out FastMail for a while, and it's pretty awesome. In some ways, it’s even better than The shortcuts for getting around are really awesome.

It almost makes me want to write an email client again, with the same power and shortcuts that FastMail has.

Computational Notebooks and MPW

Thinking more about computational notebooks (Jupyter, RunKit, etc), they are bringing up memories of MPW's worksheet, waaaay back in the day (and of course, BBEdit also has worksheets). They are very different of course, but it makes me smile to see wonderful old ideas being brought forward.

Jupyter Notebook in Nature

Nature: Why Jupyter is data scientists’ computational notebook of choice.

Jupyter notebook showed up number of times at WWDC this past year. Computational notebooks have long been a fascination of mine- VoodooPad had a number of ways to run scripts and accessing data in the various pages from those scripts. Rainier from Brent Simmons might fit that bill some day as well.

The Future of WebAssembly

Mozilla: WebAssembly’s post-MVP future: A cartoon skill tree.

I really like WebAssembly. I think it's going to enable some interesting languages and exploration in and outside the browser.

As it grows though, I worry it's going to become another JVM. And maybe it will be, but hopefully without the memory requirements and crashing nature.

October 20, 2018

Work on my FMJS is coming along. I've been trying things out, having fun looking up symbols at runtime, disassembling code, learning a bit about strict aliasing, and basically organizing things in a way that works for me.

Functions, object creation and method calls, creating, modifying, and passing around structs all work now. And I've got a little test suite using Xcode's unit test framework that's been a wonderful way to develop FMJS and make sure nothing breaks with my changes.

The biggest problem I've been running into is getting JavaScriptCore to run garbage collection in a reasonable time frame. The API for doing this, JSGarbageCollect, doesn't actually clean up unreferenced objects when you ask it to. Instead, it schedules the cleanup to happen sometime in the future. And it doesn't happen soon enough for my needs.

I have a test which allocates objects, and waits to see if they go away after cleaning up the JS runtime. They weren't being deallocated. I'm not sure what made me think of it, but I setup a runloop that just spins around until eventually JSCore decides to do it's thing between 3 and 70 seconds later. And then the test passes. But that's an extra 3-70 seconds of just sitting around waiting for my objects to be deallocated.

OK, let's print out the runloop and see what's going on:

0 : <CFRunLoopTimer 0x10a2b68b0 [0x7fffa8fe68e0]>{valid = Yes, firing = Yes, interval = 315360000, tolerance = 0, next fire date = 559929410 (-5.33140898 @ 151250457040796), callout = _ZN3JSC14JSRunLoopTimer20timerDidFireCallbackEP16__CFRunLoopTimerPv (0x7fff5537e6d0 / 0x7fff5537e6d0) (/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/JavaScriptCore), context = <CFRunLoopTimer context 0x10a7009e0>}

OK using that information I was able to find the source code on GitHub that sets up the timers for the garbage collection. In the code a JS CFRunLoopTimer is created, with an interval of a decade (60 60 24 365 10) and a firedate of a decade from when it is created.


OK, so that explains why it's not called in a reasonable time frame. But, 10 years isn't the same as 70 seconds. What's going on? Why is it being called before a 10 year time frame?

I never promised answers. And I have no idea. Runloops are magic I guess.

But, while poking around a bit more in JSCore's source, I did find this private method:

JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef);

Which does exactly what it says on the box. No runloops needed.

Obviously, this is a private API. And obviously you wouldn't want to use this in production code. But in a unit test with the right protections around it, I think it's an OK call.

But I still need to figure out how to work around the delayed garbage collection. And I suppose I should write up a radar for synchronous garbage collection.

October 18, 2018

I was complaining the other day about how Mojave still doesn't support writing 16bpc HEIC images (aka, deep color). I know most people still don't quite get why it's important, and it occurred to me that maybe there was another way to talk about it, rather than saying "more bits per pixel!" or "It's deep".

How about, "It's like @2x for color"?

So deep pixels are like @2x images. When we (developers) got our Retina displays, we didn't just size up our existing images with nearest neighbor scaling. That would have created blocky images! Instead, we added more pixels which made our curves more crisp and accurate. The same thing happens when you work with higher bits per color.

You get accuracy. You get less banding. Sure, you could dither your images to hide banding, but that's a temporary hack- sort of like subpixel antialiasing for text is (or was; Apple removed support for subpixel antialiasing in Mojave and iOS never had it).

At any rate, I filed it this past summer as radar://41731847: Mojave does not support writing 16bpc/deep color HEIC images.

The format supports it, and we've got DP3 color profiles on iOS and MacOS now. We just need the encoders to catch up.

Ironically, the introduction of a wider color gamut such as Display P3 will increase the amount of banding in our images, unless you move from 8 to 16bpc.

Brent Tells Us About Frontier

Brent Simmons: Why Create a Frontier-Inspired Scripting App?

I was bugging Brent about this the other day, and I'm happy to see him write it up. I really really like the idea of an object database, but maybe not so much the editing code in an outliner part. I'll give it a shot of course.