Things that make you go Hmmm – Cranes

I saw this notification in an email: Fri 11/18 Crane in parking lot 11/19-11/20 Building Closed

Now, it might be a sign of the times, or where I live, or my general gullability or stupidity or both, but this what my first thought:  Oh, there must be some rare bird which landed in front of that building, and they’re shutting down the building for a few days so it doesn’t get hurt.  I had visions of a rare bird, perhaps with a broken wing, maybe a whole family of cranes…

Then I thought, oh, wait, they’re talking about a construction crane, not a bird…

Just goes to show you the breadth and depth of knowledge, the openness, the empathy, that I as a programmer must possess…

Or, I’m just going senile.

 


Why is that ape wearing heels?

On this day, the interwebs brought me an interesting story.  There is this song from the C&C music factory: Things that make you go hmmm.  This story is one of those things that make you go hmmm.  You can look up the names “Pamela Ramsey Taylor” and “Beverly Whaling”, and get the general idea of what this story is about.

It’s basically about a woman freely expressing her relief that there will be a first lady in the White House who is more suitable to her sensibilities.  She uses very interesting wording, which may lead you to believe she’s some racist, or at the very least kind of clueless.  She gives apology, and the common refrain of “ask my friends, I’m not a racist!”.

Not wanting to get into all that name labeling, I just thoughts I’d drop a few words here to remind myself what really beautiful classy strong women look like.  So, here’s my short list of beautiful, strong, classy women who I would not have minded seeing in the White House over the past couple of hundred years.

  • Sally Hemmings
  • Harriet Tubman
  • Josephine Baker
  • Wilma Rudolph
  • Rosa Parks
  • Marie Daly
  • Diana Ross
  • Maya Angelou
  • Florence Griffith Joyner
  • Condolleeza Rice
  • Serena Williams
  • Rihanna
  • Michelle Obama

A slave lover to a president, a slave emancipator, entertainers, sports figures, scientists, poetic and prophetic thinkers, and world tinkerers, beauties, and sports beasts. They’re all there and tons more like them exist. They might be ‘apes’ if by that we really mean “primate”, meaning “prime, of the first order”. These ladies are all of the first order, top of the top, and any one of them could be fit to be in the White House.

I don’t think it’s helpful to shame such people that make what feel like politically incorrect statements. It just drives them underground, and in private, with their like minded friends, their echo chamber commentary will self reinforce, and erupt later forms more destructive and extreme. Rather, I would like to meet such commentary with open arms and say “what really bothered you about that? I want to understand…”

But alas, this is the day of Twitter, and; squirrel…. distraction. This story will pass, the echo chamber will exist, and everyone will run along to their next distraction.

In the meanwhile, I’m going to continue to think about which guy will look good as a first husband, when we finally get around to electing a woman to the White House.


3D Printer – Prusa i3 MK2, first impressions

wp_20161115_002

I wasn’t really looking for a new 3D printer, the Afinia H800 in the garage has been doing duty for the past year, and it’s been fine.  I have generally liked the Up! printers over the past few years, primarily for their ease of use as it relates to support material removal.  I recently took a look at a couple of reviews of this latest Prusa i3 MK2.  Prusa is a well known name in the RepRap community, and I built an earlier version of a Prusa machine, before he actually created a company for them.  That earliest experience (circa 2011) was very raw, and typical of the machines of that day, it wasn’t that great compared to the Up! of that day.

This new one caught my eye for a few reasons.  Number one is the auto bed leveling.  It has this probe thing checks 9 spots on the bed for distance and whatnot.  It does this check before every print, so it stays accurate no matter what.  Then there’s this ‘live z adjust’, which essentially is a micro adjustment that tells the distance from the probe tip to the tip of the hot end.  This allows you to really find tune the first layer of filament as it’s being deposited on the bed.  That’s really great.  It makes height adjustment really easy, as compared to trying to slide a piece of paper under the nozzle, and doing mechanical height adjustments while you do it.

There are two things about the bed that make it especially nice.  First is that the bed itself is the heated element.  There’s not a separate heating element and then the bed.  The bed is the heater.  The bed is covered with this PEI material, which seems to be better than build tak, which I use in the Afinia machine.  So far, I guess it works.  If you really need to get super sticky, you can use a glue stick, for printing PETG or Nylon I guess.  Haven’t done that yet.  After Z height adjustment, I have found that PLA sticks just fine.  I did notice curling at the edges on a few prints though.  I’ll micro adjust some more, and it should be fine.

I purchased the pre-assembled machine.  I noticed right out of the box there was a slight problem.

wp_20161112_001

Those 4 zip ties are meant to be holding the linear bearings in tight to the orange carriage.  In my case, all six of them (4 on the top bearings, 2 on the bottom) were broken.  At first I thought “oh, exercise for the reader, I’m supposed to put this final bit together”, but no, they were just broken, and needed to be replaced.  The box comes from the Czech republic, so somewhere along the line, this carriage must have really been tweeked to put enough pressure on these ties to cause them to break.  No matter though.  I had some zip ties left over from the PC build, so I was able to repair and replace.  I did not notice anything else out of whack, so I went ahead and started printing.

One of the other reasons I went with this printer is the supposed support in Windows 10s 3D Builder application.  I haven’t actually gotten that to work yet, but I should be able to print directly from whithin Windows without requiring any additional software.  That will be nice, as then I can stay within the sweetness of that Windows app.

Other than the broken ties, this machine is a good basis for playing around with a lot of stuff.  Filament loading and ejection is nice and easy, and Prusa now has a multi-color option they’re experimenting with.

At roughly $900 shipped, this printer might make for a good solid inexpensive and reliable option to build a print farm of perhaps 6 printers.  At this price, I could put together 6 printers for roughly the price of a single Type-A machines printer ($5,000).  That would give tremendous print capacity, and a solid high quality no-nonsense printer to boot.

We’ll see.


Building a Tower PC – Final assembly

Well, it’s finally done

wp_20161107_009

I began this journey with creating the excuses for doing the build in the first place, and then purchasing the various parts.


Building a tower PC – 2016


Building a Tower PC – 2016, part 1

Now here is the fully assembled thing.  Some final thoughts.  The scariest part was doing the water cooling piping.  I practiced tube bending on a waste piece before embarking on the final pieces.  Like a plumber, it’s helpful to plan out where the pipes are going, do some measurements, then do bending on cutting.  Really I was afraid that once it got assembled, it would be springing leaks all over the place ruining the fairly expensive electronics.  When I first put the tubing together, I tested by running some distilled water through the system to flush things out.

In the end, there were no leaks, and everything runs beautifully, and cool.  Having done this once now, I can see redoing the tubing at some point to make it more fancy, but for now, it works just fine, and looks cool.

One thing of note, this thing is really quiet.  You literally need to almost stick your ear into the various fans to hear them at all.  The power supply fan is dead quiet.  This is dramatically different than the power supply on my shuttle PC, which I thought was fairly quiet.  Now the Shuttle PC sounds like a jet engine in comparison.

wp_20161107_012

The fans on the cooling radiator are whisper quiet as well, and provide those cool lighting effects to boot.  Really this thing shows off best in a fairly dark room where the various glowing light effects can be seen.

The noisiest part of the entire build is actually the disk drive.  You wouldn’t normally think of that, but when things are absolutely silent, to the point where the AC fan in a room is way louder, in a quiet room, the steady rumble of the disk drive is the most notable sound.

I’m loving it so far.  I feel a sense of accomplishment in putting it together.  I got to use it as a visual aid for the latest cohort of the LEAP class.  Having a transparent case makes it easy to point at stuff, and the liquid cooling just adds a nice wow factor.

As far as the OS is concerned, I installed Windows 10 Pro.  I figure even if I want to run Linux, I can simply use Hyper-V to create Linux VMs and go that way.  Given that the graphics card can run 4 monitors at a time (I think), that’s more than enough to give me the illusion of a common desktop, with two Windows screens, and a third with Linux on a VM.  So, it’s a sweet combo.

As for the excuse to be able to run the Vulkan API on a modern graphics board, that’s coming along.  I had to install Visual Studio, build a LuaJIT, and dust off the cobwebs of my Vulkan ffi binding.  All in due time.  For now, the screaming machine is being used to type this blog post, and otherwise sitting beside my desk looking cool.  I’ll have to design a desk specifically for it just to add to the DIY nature of the thing.


Note To Self – 2016 Election

I definitely want to post this note to myself, in time capsule form, so I can look back in 4 or 8 years and see what I thought was about to happen.

More importantly than the election itself, there was a game between the Buffalo Bills and Seattle Seahawks the previous monday night (Nov 7, 2016).  There were plenty of iffy calls as usual, and one exciting one in particular at the end of the first half.  This call involved Richard Sherman disrupting a field goal attempt.  In the process of trying to block the kick, he’s clearly off sides, and ultimate touches the ball and bumps into the kicker.  At full speed, the outcome seems obvious, and the Bills of course are looking for a roughing the kicker call, which never comes.  Perplexed, the chorus of “cheater”, “dirty player”, “stupid refs” goes up in the twitter verse.  The kicker’s wife tweets something dumb, twitter verse errupts with “racism” calls, and things are just out of control.

In hindsight, and review by calmer heads, it turns out that the rules are such that if the refs don’t blow a whistle, then what Richard Sherman did is perfectly legal, even if appearing abhorant.  But, the headlines are all “Richard Sherman, dirty player, roughing the kicker non-call, the Bills could have been closer and possibly won the game in the 4th quarter”.  Woulda, coulda, shoulda.

Next day, roll forward to the US election.  Trump has been on a tare for months, saying all manner of rough and unpleasant things.  We’re all in shock and the revelations coming forward almost daily.  Democrates are salivating, not believing their luck in running against such a poor candidate.  Could not dream of a more unfit person to run against.  And yet, Hillary Clinton can’t quite seem to rise above him very far in the poles.  Certainly not the landslide inducing lead you would expect to have against such a poor candidate.  The only problem is, as poor as Trump was, Clinton appeared to be an even poorer choice.

History books will be full of analysis of why Clinton lost.  For me, it was a fairly simple formula.  She simply did not motivate the electorate to vote for her.  In an election where populist sentiment was on display, the constant non-stop country crossing of Trump, the constant Trump in the media, was just too much for the calm cerebral policy wonk speech making of the Clinton candidacy.  Just like the non-call in the Seahawks game.  The Trump supporters were like the instant tweeted response calling for dramatic change immediately.  The Clinton campaign was like the non-call, they were perhaps right, but they didn’t capture the emotion of the moment.  In the election, the emotion of the moment won out, and Trump was elected, while the cool calm and collected stayed home, or voted for someone else in protest.

Whither now?  My brother and I though Trump would win over the summer because of the way he captured the Republican party.  Just a simple recognition that he came out of the blue, and ran a campaign that the established political systems had no idea how to deal with.  They followed their traditional formulas, whereas Trump followed his reality TV success formula.  So, what happens next?

Counter to what the non-trump supporters might believe, this guy is pretty smart, regardless of all the commentary.  He is astute enough to know how to rile a crowd and get popular support.  In his first hundred days, or so, I’d expect he will do lightning strikes with executive orders.  He will try to reverse as much Obama driven stuff as possible.  This will play to his base.  In particular, he’ll go after stuff that has no real consequence, but plays well to the cheering masses.  Certainly anything related to immigration, perhaps go after a few key flag burning cases, put some investment into border security.  Roll back various rules and regulations where he can, so show that he’s getting government out of our hair.  Rudy Giuliani will become that supreme court nominee.  He could be secretary of state, but I think he would rather stay at home, and get his hands into shaping generations to come from the calm comforts of the bench.

Then, he’ll settle down and have to deal with things like the middle east, a resurgent Russia, and a China which will certainly probe and push hard.

On immigration, I’d expect that he’ll pretty much do what Obama has been doing, which is exporting as many un-documented people as is feasible.  Obama has already been doing that in record numbers, so ultimately, Trump will just continue, but will make a better show of it, actually being at the border as the buses roll up and showing the ‘adios’ as people are shown the way home.

Foreign policy, he’ll become buddy buddy with Putin.  Putin will say “Look Donald, can I call you Donald?  You don’t really care about Ukraine do you?  How about you look the other way while I just sort of annex the whole thing, and I’ll pull out of Seria?”  Trump will think, ‘yah, that sounds good, there’s no oil in the Ukraine that I care about, and I could get a win for bringing peace to the middle east, sounds like a good deal’, and that will be that.

The Phillipines might be interesting.  He’ll support strong man Duterte, and say “Look here, my daughter runs my businesses you know, I have nothing to do with those right now.  I hear she wants to build a beautiful resort in the phillipines, I don’t know.  I don’t know who the shareholders would be, but they’ll probably make a lot of money you know.  Probably well connected people in the Phillipines, I don’t know.  I do know I need to keep bases open there though.  What do you say friend?”

Looking at Nafta, ripped up and re-negotiated?  Hmmm, we’ll see on that one.  Mexico, US, Canada are a fairly strong trading block.  The US leverages Mexican workers on this side of the border to keep our various goods and services inexpensive.  We leverage workers and factories on the other side of the border for the same reason.  Large US businesses already benefit from things staying the way they are.  This is a play for the smaller companies in the US who are not competing on the global scale.  They need more protections from foreign competition (primarily Chinese goods dumping), but realistically, they simply don’t have the products at a competitive price to compete.  Short of reducing our wages to the levels seen in those foreign countries, we’re in a tough spot.  We could see some token gestures, but ultimately it comes down to having a competitive workforce in a global economy.  We need to go upscale, providing services that low wages won’t get.  And that’s the crux of a generational transformation for the American workforce.

I doubt nafta will be ‘torn up’.  The Transpacific one though, that might stall, at least until it gets negotiated in a way that will favor a post white house Trump more favorably that it might currently.

Jobs creation?  Bringing those American companies back home?  That’s also a toughy.  Those ostensibly “American” companies are international conglomerates.  Not likely to ‘repatriate’ the hundreds of billions of dollars they hold in various other countries, just to be taxed.  They’re very good at keeping that money moving, and out of the hands of tax hungry countries.  Trump knows the tax codes, and could maneuver, but again, post white house trump likely loves things to stay the way they are.

And on and on it goes.  I expect there to be a lot more attention on the white house.  I expect Trump to be very popular initially.  I expect him to put on a good enough show, and there to not be any viable candidates to oppose him, over the next 4 years.  I expect him to get reelected.  I also expect him to feel the weight of the office.  I expect the flourish he shows in the first year or two to diminish somewhat by the end of his first term.  I expect the world to continue to be a dangerous angry place as world power is rapidly shifting.  I expect the disillusioned to wake up after the end of it all and realize they’re no better off than when Obama, or Bush, or Clinton, or Bush were in office.

This is a generational inflection point.  This is what change looks like.  It’s going to be a fantastic and scary ride, and we’ll end up on a different place, on a slightly different path than we’ve been on lately.

And what else?  SpaceX, Tesla, Musk will continue to be in the news.  Azure will continue to grow, water will continue to be an issue in the middle east, the temperature will  continue to rise, diapers will continue to need changing.  I will continue to type out musings.


Elon Musk – Observing a modern space man

So, I’m not an Elon Musk acolyte.  I don’t own a Tesla, solar energy where I live isn’t particularly viable, and I don’t have any micro satellites to launch into orbit.  I feel compelled to put down my thoughts on this guy simply because I want to look back in a few years and see how my various observations panned out.

First of all, Elon Musk is human.  He’s fallable, and probably eccentric in his own way.  I’m sure there are people who love working for him, and people who hate it.  One thing is for sure, he is one of the shapers of our future modern world.  I’ll begin at my beginning.

I never heard of Elon Musk until the whole Tesla thing started.  At first he seemed to merely be a deep pocket investor, but later became the driving force of a company that probably would have gone the Fisker rout, cool tech, but not a viable business.

Then this whole economy ‘incident’ occured, and there was quite a cloud over innovation there for a while.  Tesla survived (with some government help), and what’s this?  There’s this whole other SpaceX thing which has also been brewing.  Huh.  I’m not really up on the history of SpaceX, but it appears like something cooked up by Elon Musk directly, rather than something he just so happened to invest in.  And besides that, there’s this solar city thing that was also brewing on the side, just biding it’s time through the recession.  And wait, there’s this giant factory that’s going to produce batteries, and then there’s Hyperloop.  This last one is the one that pushed me over edge in wanting to write down my thoughts on things Musk.

So, these are a bunch of wild things, each of which is giant enough to drive someone’s lifetime ambitions, but Elon Musk is into all of them.  I’m going to tray and channel him for a moment.

Elon Musk is a grown up who as a child had visions of going to Mars and setting up a colony.  He’s smart enough to have realized that going to Mars to live isn’t merely a matter of getting there, which we can probably already do.  If you really want to live there, you have to consider several things.  With any city, there’s certainly the softer sides of governance, and societal management.  Then there’s the more worrisome stuff like transportation, energy, food, shelter, water, etc.  Of you consider these latter pieces, you can begin to see the skeleton of a Mars colony in everything that he’s doing today.

SpaceX is about rocketry.  So yah, you have to work on that.  If you want to transfer people in colony sized amounts, it has to be cheap enough to achieve.  Up until SpaceX, the costs in rocketry were a bit high, largely driven by government sized entities.  SpaceX is still largely government sponsored, but they are bringing costs down through various innovations.  Of course China and India are doing much to reduce costs of space travel as well, but this is where the Boy Musk gets his excitement.

Then there’s Tesla.  It’s marginally about transportation, but it’s hugely about batteries and energy systems.  If you’re on Mars, you’re not likely to be burning fossil fuels (can’t find there, and can’t transport).  Solar energy is going to be your best bet.  Thus, Solar City makes a heck of a lot of sense.  You’ll need to develop solar panels and techniques of all sorts.  I wouldn’t be surprised if wind and some sort of thermic thing doesn’t work its way into the mix over time.  Then there’s the mega battery factory.  Oh yah sure, you can consume all those batteries in cars if you like, but really you’re creating battery systems to power houses, modules, factories, whatever.  Now, batteries aren’t the best storage for all things.  Compressed gas, or even liquids being pumped up hill might be good storage, but as far as mobile, and fairly isolated uses are concerned, traditional batteries are a good place to start.  And now, they’ve recently announced battery packs for houses, mated with solar panels of their own design, and Solar City merges with Tesla.  That’s the whole energy side of things.  I’d expect this ‘car’ company to come out with more dramatic things on the energy front.

Isn’t the car company about transportation?  Yes, marginally I think.  Hyperloop is more about transportation when it comes to Mars.  And this one really was the “aha” moment for me.  The various comments I’ve read about the feasibility of the systems really harp on things like ‘too hard to pull a vacuum to be practical’.  When you think of it from the perspective of Mars though, do the same things apply?  First of all, purchasing right of way.  I don’t know about the land grant rules related to Mars, but I’ve got to imagine that through the UN you can get a fairly large portion of Mars all to yourself.  Lay out track in tubes, either above ground, or under, and you at least don’t have right of way problems.  Creating a good enough vacuum on Mars is probably not as hard as doing it on earth, and with less gravity, moving trains requires that much less energy as well.  Given the usage of mobile battery packs (solar charged) even the energy requirements are fairly minimal.  The whole thing is solar powered.

So, for some runs, the Mars transportation system can rely on Hyperloop style conveyance.  Perhaps it’s only used to ship the various mining materials from the fields to the processing plants?  The humans can drive around in slower golf carts on short runs.

That’s the crux of how I see things unfolding for the Musketeers.  Think of everything in the context of a Mars colony.  That will drive habitation, transportation, energization, and all sorts of other ations.  In the coming years, I would expect One Musk entity or another to get more into food growth, construction, and even create an amusement part somewhere inhospitable, like the ocean floor, or the middle of the desert, in order to explore and develop concepts related to life on Mars.

That’s my view on this modern day rocket man.  At the very least, he’s inspiring a generation of thinkers and tinkers to go after this modern day moon shot.  No doubt a lot will come of it, if we don’t drown or explore ourselves first.


Splunking Windows – Extracting pleasure from legacy apis

If you are a modern programmer of Windows apps, there are numerous frameworks for you, hundreds of SDKs, scripted wrappers, IDEs to hide behind, and just layers upon layers of goodness to keep you safe and sane.  So, when it comes to using some of the core Windows APIs directly, you can be forgiven for not even knowing they exist, let alone how to use them from your favorite environment.

I’ve done a ton of exploration on the intricacies of the various Linux interfaces, Spelunking Linux goes over everything from auxv to procfs, and quite a few in between.  But, what about Windows?  Well, I’ve recently embarked on a new project lj2win32 (not to be confused with earlier LJIT2Win32).  The general purpose of this project is to bring the goodness of TINN to the average LuaJIT developer.  Whereas TINN is a massive project that strives to cover the entirety of the known world of common Windows interfaces, and provides a ready to go multi-tasking programming environment, lj2win32 is almost the opposite.  It does not provide its own shell, rather it just provides the raw bindings necessary for the developer to create whatever they want.  It’s intended to be a simple luarocks install, much in the way the ljsyscall works for creating a standard binding to UNIX kinds of systems without much fuss or intrusion.

In creating this project, I’ve tried to adhere to a couple of design principles to meet some objectives.

First objective is that it must ultimately be installable using luarocks.  This means that I have to be conscious about the organization of the file structure.  To wit, everything of consequence lives in a ‘win32’ directory.  The package name might ultimately be ‘win32’.  Everything is referenced from there.

Second objective, provide the barest minimum bindings.  Don’t change names of things, don’t introduce non-windows semantics, don’t create several layers of class hierarchies to objectify the interfaces.  Now, of course there are some very simple exceptions, but they should be fairly limited.  The idea being, anyone should be able to take this as a bare minimum, and add their own layers atop it.  It’s hard to resist objectifying these interfaces though, and everything from Microsoft’s ancient MFC, ATL, and every framework since, has thrown layers of object wrappers on the core Win32 interfaces.  In this case, wrappers and other suggestions will show up in the ‘tests’ directory.  That is fertile ground for all manner of fantastical object wrapperage.

Third objective, keep the dependencies minimal.  If you do programming in C on Windows, you include a couple of well known headers files at the beginning of your program, and the whole world gets dragged in.  Everything is pretty much in a global namespace, which can lead to some bad conflicts, but they’ve been worked out over time.  In lj2win32, there are only a couple things in the global namespace, everything else is either in some table, or within the ffi.C facility.  Additionally, the wrappings are clustered in a way that follows the Windows API Sets.  API sets are a mechanism Windows has for pulling apart interdependencies in the various libraries that make up the OS.  In short, it’s just a name (so happens to end in ‘.dll’) which is used by the loader to load in various functions.  If you use these special names, instead of the traditional ‘kernel32’, ‘advapi32’, you might pull in a smaller set of stuff.

With all that, I thought I’d explore one particular bit of minutia as an example of how things could go.

The GetSystemMetrics() function call is a sort of dumping ground for a lot of UI system information.  Here’s where you can find things like how big the screen is, how many monitors there are, how many pixels are used for the menu bars, and the like.  Of course this is just a wrapper on items that probably come from the registry, or various devices and tidbits hidden away in other databases throughout the system, but it’s the convenient developer friendly interface.

The signature looks like this

int WINAPI GetSystemMetrics(
_In_ int nIndex
);

A simple enough call. And a simple enough binding:

ffi.cdef[[
int GetSystemMetrics(int nIndex);
]]

Of course, there is the ‘nIndex’, which in the Windows headers is a bunch of manifest constants, which in LuaJIT might be defined thus:

ffi.cdef[[
	// Used for GetSystemMetrics
static const int	SM_CXSCREEN = 0;
static const int	SM_CYSCREEN = 1;
static const int	SM_CXVSCROLL = 2;
static const int	SM_CYHSCROLL = 3;
static const int	SM_CYCAPTION = 4;
static const int	SM_CXBORDER = 5;
static const int	SM_CYBORDER = 6;
]] 

 
Great. Then I can simply do

local value = ffi.C.GetSystemMetrics(ffi.C.SM_CXSCREEN)

 
Fantastic, I’m in business!

So, this meets the second objective of bare minimum binding. But, it’s not a very satisfying programming experience for the LuaJIT developer. How about just a little bit of sugar? Well, I don’t want to violate the same second objective of non-wrapperness, so I’ll create a separate thing in the tests directory. The systemmetrics.lua file contains a bit of an exploration in getting of system metrics.

It starts out like this:

local ffi = require("ffi")
local errorhandling = require("win32.core.errorhandling_l1_1_1");

ffi.cdef[[
int GetSystemMetrics(int nIndex);
]]

local exports = {}

local function SM_toBool(value)
	return value ~= 0
end

Then defines something like this:

exports.names = {
    SM_CXSCREEN = {value = 0};
    SM_CYSCREEN = {value = 1};
    SM_CXVSCROLL = {value = 2};
    SM_CYHSCROLL = {value = 3};
    SM_CYCAPTION = {value = 4};
    SM_CXBORDER = {value = 5};
    SM_CYBORDER = {value = 6};
    SM_CXDLGFRAME = {value = 7};
    SM_CXFIXEDFRAME = {value = 7};
    SM_CYDLGFRAME = {value = 8};
    SM_CYFIXEDFRAME = {value = 8};
    SM_CYVTHUMB = {value = 9};
    SM_CXHTHUMB = {value = 10};
    SM_CXICON = {value = 11};
    SM_CYICON = {value = 12};
    SM_CXCURSOR = {value = 13};
    SM_CYCURSOR = {value = 14};
    SM_CYMENU = {value = 15};
    SM_CXFULLSCREEN = {value = 16};
    SM_CYFULLSCREEN = {value = 17};
    SM_CYKANJIWINDOW = {value = 18, converter = SM_toBool};
    SM_MOUSEPRESENT = {value = 19, converter = SM_toBool};
    SM_CYVSCROLL = {value = 20};
    SM_CXHSCROLL = {value = 21};
    SM_DEBUG = {value = 22, converter = SM_toBool};
    SM_SWAPBUTTON = {value = 23, converter = SM_toBool};
    SM_RESERVED1 = {value = 24, converter = SM_toBool};
    SM_RESERVED2 = {value = 25, converter = SM_toBool};
    SM_RESERVED3 = {value = 26, converter = SM_toBool};
    SM_RESERVED4 = {value = 27, converter = SM_toBool};
}

And finishes with a flourish like this:

local function lookupByNumber(num)
	for key, entry in pairs(exports.names) do
		if entry.value == num then
			return entry;
		end
	end

	return nil;
end

local function getSystemMetrics(what)
	local entry = nil;
	local idx = nil;

	if type(what) == "string" then
		entry = exports.names[what]
		idx = entry.value;
	else
		idx = tonumber(what)
		if not idx then 
			return nil;
		end
		
		entry = lookupByNumber(idx)

        if not entry then return nil end
	end

	local value = ffi.C.GetSystemMetrics(idx)

    if entry.converter then
        value = entry.converter(value);
    end

    return value;
end

-- Create C definitions derived from the names table
function exports.genCdefs()
    for key, entry in pairs(exports.names) do
        ffi.cdef(string.format("static const int %s = %d", key, entry.value))
    end
end

setmetatable(exports, {
	__index = function(self, what)
		return getSystemMetrics(what)
	end,
})

return exports

All of this allows you to do a couple of interesting things. First, what if you wanted to print out all the system metrics. This same technique can be used to put all the metrics into a table to be used within your program.

local sysmetrics = require("systemmetrics");

local function testAll()
    for key, entry in pairs(sysmetrics.names) do
        local value, err = sysmetrics[key]
        if value ~= nil then
            print(string.format("{name = '%s', value = %s};", key, value))
        else
            print(key, err)
        end
    end
end

OK, so what? Well, the systemmetrics.names is a dictionary matching a symbolic name to the value used to get a particular metric. And what’s this magic with the ‘sysmetrics[key]’ thing? Well, let’s take a look back at that hand waving from the systemmetrics.lua file.

setmetatable(exports, {
	__index = function(self, what)
		return getSystemMetrics(what)
	end,
})

Oh, I see now, it’s obvious…

So, what’s happening here with the setmetatable thing is, Lua has a way of setting some functions on a table which will dictate the behavior they will exhibit in certain situations. In this case, the ‘__index’ function, if it exists, will take care of the cases when you try to look something up, and it isn’t directly in the table. So, in our example, doing the ‘sysmetrics[key]’ thing is essentially saying, “Try to find a value with the string associated with ‘key’. If it’s not found, then do whatever is associated with the ‘__index’ value”. In this case, ‘__index’ is a function, so that function is called, and whatever that returns becomes the value associated with that key.

I know, it’s a mouth full, and metatables are one of the more challenging aspects of Lua to get your head around, but once you do, it’s a powerful concept.

How about another example which will be a more realistic and typical case.

local function testSome()
    print(sysmetrics.SM_MAXIMUMTOUCHES)
end

In this case, the exact same mechanism is at play. In Lua, there are two ways to get a value out of a table. The first one we’ve already seen, where the ‘[]’ notation is used, as if the thing were an array. In the ‘testSome()’ case, the ‘.’ notation is being utilized. This is accessing the table as if it were a data structure, but it’s exactly the same as trying to access as an array, at least as far as the invocation of the ‘__index’ function is concerned. The ‘SM_MAXIMUMTOUCHES’ is taken as a string value, so it’s the same as doing: sysmetrics[‘SM_MAXIMUMTOUCHES’], and from the previous example, we know how that works out.

Now, there’s one more thing to note from this little escapade. The implementation of the helper function:

local function getSystemMetrics(what)
	local entry = nil;
	local idx = nil;

	if type(what) == "string" then
		entry = exports.names[what]
		idx = entry.value;
	else
		idx = tonumber(what)
		if not idx then 
			return nil;
		end
		
		entry = lookupByNumber(idx)

        if not entry then return nil end
	end

	local value = ffi.C.GetSystemMetrics(idx)

    if entry.converter then
        value = entry.converter(value);
    end

    return value;
end

There’s all manner of nonsense in here. The ‘what’ can be either a string or something that can be converted to a number. This is useful because it allows you to pass in symbolic names like “SM_CXBLAHBLAHBLAH” or a number 123. That’s great depending on what you’re interacting with and how the values are held. You might have some UI for example where you just want to use the symbolic names and not deal with numbers.

The other thing of note is that ‘entry.converter’ bit at the end. If you look back at the names table, you’ll notice that some of the entries have a ‘converter’ field associated with them. this is an optional function that can be associated with the entries. If it exists, it is called, with the value from the system called passed to it. In most cases, what the system returns is a number (number of mouse buttons, size of screen, etc). In some cases, the value returned is ‘0’ for false, and ‘non-zero’ for true. Well, as a Lua developer, I’d rather just get a bool in those cases where it’s appropriate, and this helper function is in a position to provide that for me. This is great because it allows me to not have to check the documentation to figure it out.

There’s one more tiny gem hidden in all this madness.

function exports.genCdefs()
    for key, entry in pairs(exports.names) do
        ffi.cdef(string.format("static const int %s = %d", key, entry.value))
    end
end

What does this do exactly? Simply, it generates those constants in the ffi.C space, so that you can still do this:

ffi.C.GetSystemMetrics(ffi.C.SM_MAXIMUMTOUCHES)

So, there you have it. You can go with the raw traditional sort of ffi binding, or you can spice things up a bit and make things a bit more useful with a little bit of effort. I like doing the latter, because I can generate the more traditional binding from the table of names that I’ve created. That’s a useful thing for documentation purposes, and in general.

I have stuck to my objectives, and this little example just goes to prove how esoteric minute details can be turned into approachable things of beauty with a little bit of Lua code.