dmd support for IDEs + network GUI

Adam D. Ruppe destructionator at gmail.com
Mon Oct 12 16:53:32 PDT 2009


On Mon, Oct 12, 2009 at 07:09:11PM -0400, Nick Sabalausky wrote:
> What you say here is actually hinting at what I meant: What we need is a 
> proper GUI equivalent to something like TTY or telnet. Not remote desktops, 
> which really just act like streaming video, but something that'll say "Hey 
> client, host here, talking through something much more appropriate than 
> XML/HTTP, I want a button that says 'Ok' at (7,14) with size (50,20) on the 
> form 'FooForm', and if the user wants a skin, may I suggest (but not insist) 
> the 'buttonSkinFoo' that I already sent you earlier, plus I need a 
> user-editable textbox over here...etc." (In fact, I think X11 already 
> provides something like this in a slightly more low-level form)

X11 is too low level - it works on windows and drawing commands, but that's
about it. Windows Remote Desktop is actually in a much better position, but
it is still fairly slow for its own reasons.

My DWS project aims to work up on a widget level. It isn't quite as visually
fancy as what you are describing (though it could grow into it later), but
works on a high enough level of abstraction to be fast - and cross platform.

One of the things that makes X feel slow is that it needs to make a lot of
round-trips to the server to get anything done. (And the modern toolkits make
this *worse* by shoehorning in features the low level protocol wasn't really
meant to support.)

To solve this, I want to hand off as much processing as possible to the client.
And to make that happen, I say you shouldn't be too concerned about the
specifics. Tell what widgets you want, but leave the specifics to the viewer.

This also gives a bonus for cross platform: when using an app on Windows,
the little details should feel like a Windows program, not a Linux one, even
if the app itself is running on a Linux server somewhere.


One the apps I already have running on it is a notepad program. The code
looks like this:

---
auto app = new DWSApp;

auto  window = new MainWindow;
window.title = "My notepad";

auto editBox = new TextEdit(window);

auto menu = new Menu("File");
menu.addItem(new Action("Save", { std.file.write("file.txt", editbox.text); }));

window.addMenu(menu);

window.show;

app.exec();
---


Most the lines turn into network calls pretty directly. The protocol is
binary, so no wasted time parsing text and no wasted bandwidth on bloated
stuff like XML. It works on an always open connection, so no annoying lag
from stupid nonsense like HTTP polling.


The window, menu, and edit box are created however the viewer wants to do it.
Currently, I have a Qt/C++ viewer that uses Qt widgets for the actual
implementation, but this can be anything - I want to do a MS-DOS text mode
viewer eventually to demonstrate the flexibility.



A network session would look something like this (each function name is just
one byte show down the wire and the arguments are mostly plain ints):

createWindow(0); // the argument is the window ID - you tell the server, so you
	// can use it immediately without waiting on the lag of a response
	// the D language API hides this from you though as a private member
createWidget(TEXT_EDIT, 0);
createMenu(0, "File"); // strings are sent across as length ~ data
createAction(0, "Save");
addActionToMenu(0, 0); // menuId, actionId
showWindow(0);


That's just 24 bytes of payload to create the window, no round trip required
(except for the ACK from TCP).


Now, the user starts typing. His text appears instantly - the computer he is
in front of handles the text widget all on its own. The only thing it sends
back on the wire:

widgetTextUpdate(0, /* description of text changes since last update */);

It doesn't need to wait on the program's response - it doesn't care. It just
sends this update back to boost speed on future operations and to provide
crash protection. (If the viewing computer crashes, or if the network link
suddenly dies, the app knows its state, so it can recreate the window when
the network comes back. Also useful for migrating the app display to another
machine.)

You don't have an X11 style

 > keyEvent('a');
 < drawText('a');

back and forth.


What if the user clicks the menu item? Easy:

  widgetTextUpdate(); // it flushes updates to ensure the app sees the most
  			// recent text
  actionTriggered(0); // the D API sees these 2 bytes on the wire and calls
  			// the delegate I passed in the code.



That's it!

The entire session to edit a quick text file might have only two required 
round trips to the server - it sips bandwidth and is latency tolerant.



More complex programs that can't be built on the ~20 standard widgets will
be slower, since they'll have to actually subscribe to the low level key
events, etc., but I have a plan (not yet implemented at all) to fix that too
by caching event paths.

Basically, your app tells the viewer as much as it can to handle little things
on its own. "When the user presses 'A', go ahead and draw the letter A at
the cursor, but then tell me so I can do fancier processing too."

This, not being written in any code at all, however, is subject to change.
I'm not sure how well it will actually work in real apps.




Nevertheless, even if there is a requirement for special widgets to be
slow and talk to the server for everything, the majority of cases should
be covered by the standard widgets, giving a big boost overall.



In addition to GUI components, I also want to support local file and
sound access, along with a few other things. It sucks when you are using
an X program and it decides to blare sound out of your home computer when
you are using the app from your work computer!

Or it is a real pain in the ass to have to save the file in X, then scp
it over to open it in a local program.

These things should Just Work, and it isn't hard to implement, so I'll be
setting that up too.

-- 
Adam D. Ruppe
http://arsdnet.net



More information about the Digitalmars-d mailing list