gdc 11 out with a lot of D updates

Posted 2021-05-31

Several interesting community announcements this week: a lightweight D runtime, gdc 11, the IRC channel moved, string interpolation evolves, and more. Also, I continue to work on my projects.

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

Random thoughts

That LWDR's readme has a note at the bottom that in used my webassembly stuff as a base. This is nice - someone is getting my point that D with custom or minimal runtime actually can do good work!

The nice thing about the betterC switch is it gives a lowest common denominator for niche library authors, and it is ok for some small other specialized tasks, but every time it is used for an actual application it pains me a little since a custom druntime quickly becomes a better approach. You keep all the minimalist benefits without limiting your potential.

The core team talks about pay-as-you-go druntime, which I think is the holy grail - it will help in all these special cases and simultaneously keep the regular D builds a bit leaner too - but it also isn't going be around for... who knows.

For what we have right now, a pre-packaged mini druntime like this is surely going to help bridge the gap. Glad to see it.

What Adam is working on

D documentation

adrdox master now supports this code a bit better:

/++ Some note +/
int a, b, c;

Previously, it would copy the doc for each one and move on. Now, it still does that, but it treats it more like ditto comments, retaining a "related to" link in the docs, grouping them together.

Meanwhile, on the dpldocs website, the clear cache behavior is more transactional than it used to be. Previously, it was a really simple, lazy hack: it literally deleted the cache file and redirected the user to the rebuild page, where they had to wait for it to finish.

If the user hit "stop" in their browser, it would cancel the build and leave it broken for everyone.

Now, it instead kicks off a background job to rebuild it and keeps the old files around to rollback in the event of failure, so while the site might not actually update, it at least doesn't break it for everyone anymore.

This should fix a lot of the dead links and broken searches that pop up from time to time.

minigui

I continue working on my 2.0 project preparing it for release, but I also revisited my thing from November of last year: declarative gui in D.

I hacked that together then and recently decided to clean it up a little more as part of the 2.0 polish. I removed some code duplication and enhanced features between that and the old @menu uda work.

Those of you who follow me on other websites or who were on the MILKCONF (aka beerconf, an online hangout we stay on for about 40 hours, come and go, once a month) call over the weekend have seen this before but I quite like it:

The "data controller widget" demo on screen shows a rectangle drawn on the top side of the window

That window is created by the following 50ish lines of code:

import arsd.minigui;
import arsd.minigui_addons.nanovega;

void main() {
	auto window = new Window();

        @Container!(VerticalLayout, Style.maxHeight(64))(
		"Randomize",
		Container!HorizontalLayout("default")
	)
	static struct Position {
		@ControlledBy!HorizontalSlider(0, 2000, 1)
		int x = 1000;
		@ControlledBy!VerticalSlider(0, 2000, 1)
		int y = 1000;

		void Reset() {
			this = this.init;
		}

		void Randomize() {
			import std.random;
			x = uniform(0, 2000);
			y = uniform(0, 2000);
		}

		string color1 = "#f00";
		string color2 = "#00f";
	}

	Position position;

	auto w = new NanoVegaWidget(window);
	w.redrawNVGScene = (nvg) {
		nvg.beginPath();
		nvg.roundedRect(position.x * w.width / 2000 - 15, position.y * w.height / 2000 - 15, 30, 30, 8);
		nvg.fillPaint = nvg.linearGradient(0, 0, w.width, w.height, NVGColor(position.color1), NVGColor(position.color2));
		nvg.fill();
	};

	auto dcw = window.addDataControllerWidget(&position, w);

	w.addEventListener((MouseMoveEvent mme) {
		if(mme.state & ModifierState.leftButtonDown) {
			position.x = mme.clientX * 2000 / w.width;
			position.y = mme.clientY * 2000 / w.height;
			dcw.notifyDataUpdated();
		}
	});

	window.loop();
}

You can see how I try to merge declarative and immediate gui concepts with the traditional widgets that form the foundation of the minigui library. You can draw from the data and control from the struct, in addition to setting other events as you need them.

The notifyDataUpdated function kinda disappoints me, but it is practically necessary since there's no other hook on the struct data. I suppose I could just poll for changes on a timer or in a background thread or something, but that's just disgusting to me.

You'll notice it isn't called in the public methods - when you click the randomize button, for example, it just works, but that's because those widgets are created by the library, so it just assumes that after the public method is called, it probably changed something, so it updates everything off the object afterward. If the method is called through another path though, you also need to notifyDataUpdated.

Similarly, when the data is updated, it needs to tell the display widget to redraw. This is why it took the w argument to addDataControllerWidget - that's an optional param it assumes draws, so it queues up its redraw any time it detects a change.

It isn't quite as magical as I'd like.... but it is still pretty cool the way it works.

And now since this is merged with the other stuff, I can add other things:

@menu("Stuff") {
	@toolbar("foo")
	@accelerator("Ctrl+R")
	void Randomize() {
		import std.random;
		x = uniform(0, 2000);
		y = uniform(0, 2000);
	}

	void change(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

And call window.setMenuAndToolbarFromAnnotatedCode(position); to process all those and add it to a menu, set a keyboard shortcut and toolbar icon to the Randomize method/button, and that new change button - notice that it takes parameters - actually pops up a dialog box to ask for them.

Screenshot showing the dialog box asking for X and Y parameters after clicking the auto-generated "change" button

With these functions merged, there's a lot of potential here as I continue to flesh it out.

All the screenshots are from my Linux box btw, on Windows they would look native (because they ARE native controls) and you can now restyle things too:

dark theme minigui screenshot

So if you don't like my style, it is getting easier to change it.

Well, I'll be continuing to clean this up and document it, soon the release will be made. In the mean time though, git master already has most the updates if you want to goof around with it yourself, just remembers I'm still changing stuff every day.