comp.lang.ada
 help / color / mirror / Atom feed
* [OT] Best way to isolate a GUI?
@ 2003-02-16 10:19 Jano
  2003-02-16 14:47 ` Ed Falis
                   ` (7 more replies)
  0 siblings, 8 replies; 57+ messages in thread
From: Jano @ 2003-02-16 10:19 UTC (permalink / raw)


Hello,

as for my (lately) frequent questions, you may be aware I'm starting a 
new project in Ada. Well, the matter is that I want the core 
functionality to be isolated from the GUI. And that's the question: 
how's the best mean to do that.

I've thought the following:

1) Use AWS and let any browser do the rendering. That's not really 
isolating the GUI, because all the generating code would be inside the 
core (unless I also apply):

2) Use sockets to communicate the two processes.
2.a) Use regular Ada streams to pass data types.
2.b) Use some other protocol, for example [compressed] XML.

3) Your sugestions welcome.

I would want that the isolation be such any kind of GUI can be build on 
top. Maybe even made two of them run concurrently. For example, web 
reports via AWS and a control GUI with native look.

Any have prior experience? Some successful example on the wild to check?

Thanks in advance,

-- 
-------------------------
Jano
402450[at]cepsz.unizar.es
-------------------------



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
@ 2003-02-16 14:47 ` Ed Falis
  2003-02-16 14:49 ` Victor Porton
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 57+ messages in thread
From: Ed Falis @ 2003-02-16 14:47 UTC (permalink / raw)


I'd take a look at a book like "Pattern Oriented Software Architecture" 
by Busch et al where the issue of GUI separation is treated abstractly 
and the various tradeoffs are considered, before jumping to a possible 
solution implementation.

- Ed




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
  2003-02-16 14:47 ` Ed Falis
@ 2003-02-16 14:49 ` Victor Porton
  2003-02-17 20:52   ` Jano
  2003-02-16 16:36 ` Robert C. Leif
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 57+ messages in thread
From: Victor Porton @ 2003-02-16 14:49 UTC (permalink / raw)


In article <MPG.18b98425db7e9aef989698@news.cis.dfn.de>,
	Jano <402450@cepsz.unizar.es> writes:
> as for my (lately) frequent questions, you may be aware I'm starting a 
> new project in Ada. Well, the matter is that I want the core 
> functionality to be isolated from the GUI. And that's the question: 
> how's the best mean to do that.
> 
> I've thought the following:
> 
> 2) Use sockets to communicate the two processes.
> 2.a) Use regular Ada streams to pass data types.
> 2.b) Use some other protocol, for example [compressed] XML.

Ada has partitions for this! (See RM.)



^ permalink raw reply	[flat|nested] 57+ messages in thread

* RE: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
  2003-02-16 14:47 ` Ed Falis
  2003-02-16 14:49 ` Victor Porton
@ 2003-02-16 16:36 ` Robert C. Leif
  2003-02-17  8:44   ` Preben Randhol
  2003-02-16 17:25 ` achrist
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 57+ messages in thread
From: Robert C. Leif @ 2003-02-16 16:36 UTC (permalink / raw)
  To: 'comp.lang.ada mail to news gateway'

In principle, the best way to isolate the GUI is to use XForms with XML. One
can now download an XForms tool that works with Windows,
http://www.formsplayer.com/. I believe that there are similar tools for
Linux. The next step is to write the Ada software to interface with XForms.
It should be possible to build an Ada windowing package based on XForms and
other XML documents. This would provide both operating system independence
and the capacity to interact with the next version of Microsoft Office. The
present Ada GUI tools and screen generators could be extended for this
purpose.
Bob Leif

-----Original Message-----
From: Jano [mailto:402450@cepsz.unizar.es] 
Sent: Sunday, February 16, 2003 2:20 AM
To: comp.lang.ada@ada.eu.org
Subject: [OT] Best way to isolate a GUI?

Hello,

as for my (lately) frequent questions, you may be aware I'm starting a 
new project in Ada. Well, the matter is that I want the core 
functionality to be isolated from the GUI. And that's the question: 
how's the best mean to do that.

I've thought the following:

1) Use AWS and let any browser do the rendering. That's not really 
isolating the GUI, because all the generating code would be inside the 
core (unless I also apply):

2) Use sockets to communicate the two processes.
2.a) Use regular Ada streams to pass data types.
2.b) Use some other protocol, for example [compressed] XML.

3) Your sugestions welcome.

I would want that the isolation be such any kind of GUI can be build on 
top. Maybe even made two of them run concurrently. For example, web 
reports via AWS and a control GUI with native look.

Any have prior experience? Some successful example on the wild to check?

Thanks in advance,

-- 
-------------------------
Jano
402450[at]cepsz.unizar.es
-------------------------




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
                   ` (2 preceding siblings ...)
  2003-02-16 16:36 ` Robert C. Leif
@ 2003-02-16 17:25 ` achrist
  2003-02-16 21:24 ` Bobby D. Bryant
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 57+ messages in thread
From: achrist @ 2003-02-16 17:25 UTC (permalink / raw)


Here's one way to do it.

(1) Write the GUI in TCL (Use a GUI builder for Tcl).
(2) Write the functionality in Ada.  Package it as a DLL, COM server,
	or shared library.
(3) Write the connection between the GUI and the functionality in C/C++
	using Tcl.h and Tk.h. 


Al


Jano wrote:
> 
> Hello,
> 
> as for my (lately) frequent questions, you may be aware I'm starting a
> new project in Ada. Well, the matter is that I want the core
> functionality to be isolated from the GUI. And that's the question:
> how's the best mean to do that.
> 
> I've thought the following:
> 
> 1) Use AWS and let any browser do the rendering. That's not really
> isolating the GUI, because all the generating code would be inside the
> core (unless I also apply):
> 
> 2) Use sockets to communicate the two processes.
> 2.a) Use regular Ada streams to pass data types.
> 2.b) Use some other protocol, for example [compressed] XML.
> 
> 3) Your sugestions welcome.
> 
> I would want that the isolation be such any kind of GUI can be build on
> top. Maybe even made two of them run concurrently. For example, web
> reports via AWS and a control GUI with native look.
> 
> Any have prior experience? Some successful example on the wild to check?
> 
> Thanks in advance,
> 
> --
> -------------------------
> Jano
> 402450[at]cepsz.unizar.es
> -------------------------



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
                   ` (3 preceding siblings ...)
  2003-02-16 17:25 ` achrist
@ 2003-02-16 21:24 ` Bobby D. Bryant
  2003-02-16 21:52 ` David Marceau
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 57+ messages in thread
From: Bobby D. Bryant @ 2003-02-16 21:24 UTC (permalink / raw)


On Sun, 16 Feb 2003 11:19:34 +0100, Jano wrote:

> as for my (lately) frequent questions, you may be aware I'm starting a
> new project in Ada. Well, the matter is that I want the core
> functionality to be isolated from the GUI. And that's the question:
> how's the best mean to do that.

Whatever else you do, try it on a tiny project first.

-- 
Bobby Bryant
Austin, Texas




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
                   ` (4 preceding siblings ...)
  2003-02-16 21:24 ` Bobby D. Bryant
@ 2003-02-16 21:52 ` David Marceau
  2003-02-17  0:57 ` Re; " tmoran
  2003-02-18 13:08 ` Marin David Condic
  7 siblings, 0 replies; 57+ messages in thread
From: David Marceau @ 2003-02-16 21:52 UTC (permalink / raw)


Jano wrote:
> 
> Hello,
> 
> as for my (lately) frequent questions, you may be aware I'm starting a
> new project in Ada. Well, the matter is that I want the core
> functionality to be isolated from the GUI. And that's the question:
> how's the best mean to do that.
Define an api being a set of services which you promise not to change in
the future and will remain.
If ever there needs changing, your api will grow.  If a service needs
one more parameter, add a service with the same name but increment the
service name i.e. adaToBlahLANGUAGE(someAdaType, someBLAHLANGUAGETYPE)
has another similar service adaToBlahLANGUAGE2.
I am certainly not encouraging adding parameters to services.  The
number of parms should be kept to a minimum always to reduce service
complexity.
The api will do a few things:
1)convert data from ada to a destination language
2)convert data from a source language to ada
3)receive data from a source language 
4)send data to target language
5)in general other languages understand c types so usually that's the
target language and language type used to 
send and receive along with some other information.  i.e.  Ada to C to
TCL, or Ada to C to Java, Ada to XmlAda to AWS to XMLsocket to Flash
Actionscript, Ada to ming to swf to aws to web browser flash.
6)like file/socket apis, consider using a handle as the first parm for
all the services in the api itself.  Consider it as an escape mechanism
for using global vars in your api via some services to request the
global data when necessary.
7)As a rule of thumb two or three more parms is acceptable.  Getting
beyond that number is going to require a great deal of justification
IMHO.  For example setting and getting an object attribute requires a
handle, the object and a default/setValue.  Ideally after preparing an
object by setting some attributes you wish it to do something useful. 
That useful service ideally would have a return value somewhere as a
parameter or a real "return value" and that's it.  Keep in mind a return
value or a parameter for a service may be an object with many
attributes.  This object may even represent a tree object.  That is why
many parameters should not be necessary.  This will keep the api highly
maintainable.  This is an approach that can be used in any language.

This approach is absolutely necessary for backward compatibility in both
binaries and source.  If ever someone breaks this rule usually it shows
up with symptoms later on due to complexity and bugs :)

> 
> I've thought the following:
> 
> 1) Use AWS and let any browser do the rendering. That's not really
> isolating the GUI, because all the generating code would be inside the
> core (unless I also apply):
> 
> 2) Use sockets to communicate the two processes.
> 2.a) Use regular Ada streams to pass data types.
> 2.b) Use some other protocol, for example [compressed] XML.
> 
> 3) Your sugestions welcome.
> 
> I would want that the isolation be such any kind of GUI can be build on
> top. Maybe even made two of them run concurrently. For example, web
> reports via AWS and a control GUI with native look.
> 
> Any have prior experience? Some successful example on the wild to check?
> 
> Thanks in advance,
> 
> --
> -------------------------
> Jano
> 402450[at]cepsz.unizar.es
> -------------------------
How about:
1)get flash mx player
2)get ming sdk(flash file generator)
3)get aws(ada web server)
4)get example actionscript for flash mx.
5)Build a prototype in flash mx.
6)rewrite the prototype as c/ming code to generate swf.  Shove the
generated swf to the web browser on the client side creating the gui.
7)make whatever communication from the browser go to AWS via XMLsocket
in flash's actionscript which resembles javascript.
8)This doesn't imply an ada binding to ming however ideally it could.
9)This does imply some c code in the solution however if the ada
bindings existed it wouldn't have to.
10)Although this does imply embedded actionscript into ada/c code, it is
equivalent to the TCL/TASH approach IMHO :)

Keeping in mind you want two different kinds of gui structures:
1)get ada web server
2)explicitly require anybody connecting with your web browser download
the tcl plug-in to install in the web browser.
3)build a prototype in tclscript
4)shove the tclscript to the web browser on the client side creating the
gui.
5)communicate with sockets to AWS from the tclscript.(I don't know if
this is allowed since I have never used the tcl-plugin.)
I would imagine it should be possible.  Xml what the hell not that I am
a fan.
6)this implies embedded tclscript in the ada code to generate the
interface.


As you can see there are two guis served up by aws, flash and
tclscript.  Actually three if you count html forms :)
How you split up the tiers is up to you.  But I could imagine a few
layers:
1)tcl gui in ada(request and response)
2)flash gui in ada(request and response)
3)html gui in ada(request and response)

4)aws in ada

5)business rules in ada, prolog, clips...

6)data storage in ada, sql...

Keep in mind such a flash/ming/ada approach is not that bad considering
there are flash players for pdas, cellulars and computers.

> top. Maybe even made two of them run concurrently. For example, web
> reports via AWS and a control GUI with native look.
I'm not so sure a native look is anyone intentions.  I think you really
mean "intended look and feel".
IMHO We are more concerned the functionality and the look remain the
same on all platforms.
Keep in mind what we all want is that the GUI remain the same look and
feel as we intended where we built it.
That's why I think flash is extremely versatile.  IMHO it seems to
deliver a gui faithful to the intentions of the designer 
on all platforms flash runs on.  That said when you do make the gui IMHO
you have to keep in mind the lowest common denominator. 
i.e. When you scale down a gui to the device with the least pixel real
estate, will the gui be acceptable after the scaling down?
In order to avoid this, it is a good idea to make the gui with the
smallest pixel real estate first and then scale up :)
At least this way the resulting gui is guaranteed to display correctly
on all devices the first shot because the aspect ratio in Flash is
preserved.

Of course you could always choose to build a java gui and communicate
with sockets via your web browser.
Whatever language you use won't change the number of tiers in the
design.  Other factors will change your design which have less to do
with gui and more to do with overall performance.

I hope this helps.

Cheers,
David Marceau



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re; [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
                   ` (5 preceding siblings ...)
  2003-02-16 21:52 ` David Marceau
@ 2003-02-17  0:57 ` tmoran
  2003-02-17  7:25   ` Jano
  2003-02-18 13:08 ` Marin David Condic
  7 siblings, 1 reply; 57+ messages in thread
From: tmoran @ 2003-02-17  0:57 UTC (permalink / raw)


> I want the core functionality to be isolated from the GUI.
What do you mean here by "the GUI"?  If your app is a Photoshop type
program, or a video editor or a spreadsheet or a control panel for a robot
undersea explorer or a database of names and addresses, or a Virtual
Reality program or a "twitch game".....  you will have different
requirements for your "Graphical User Interface" and, most likely,
different optimal solutions.



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Re; [OT] Best way to isolate a GUI?
  2003-02-17  0:57 ` Re; " tmoran
@ 2003-02-17  7:25   ` Jano
  2003-02-17 14:09     ` Bobby D. Bryant
  0 siblings, 1 reply; 57+ messages in thread
From: Jano @ 2003-02-17  7:25 UTC (permalink / raw)


En el mensaje <UrW3a.144381$Ec4.143958@rwcrnsc52.ops.asp.att.net>, 
tmoran@acm.org dice...

> > I want the core functionality to be isolated from the GUI.
> What do you mean here by "the GUI"?  If your app is a Photoshop type
> program, or a video editor or a spreadsheet or a control panel for a robot
> undersea explorer or a database of names and addresses, or a Virtual
> Reality program or a "twitch game".....  you will have different
> requirements for your "Graphical User Interface" and, most likely,
> different optimal solutions.

I'm reading all responses and am a little ashamed about the complexity 
this matter has revealed... I was expecting it to be a little simpler...

Anyways, I not need to be secretive about my project, since is a 
personal one. I'm trying to implement a basic Gnutella servant, just to 
improve my skills in Ada. You see now what's the core and what's the 
GUI...

My background in Ada is so-so: I've been teached the core features of 
Ada 83 and tasking capabilities of Ada 95, and have already finished an 
small hard realtime monitoring system, as experience accounts. OO 
things, I've read some eBooks but not used them in any real project.

I'm digesting your responses, please keep these insightful advices 
coming.

-- 
-------------------------
Jano
402450[at]cepsz.unizar.es
-------------------------



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 16:36 ` Robert C. Leif
@ 2003-02-17  8:44   ` Preben Randhol
  2003-02-17 16:22     ` Robert C. Leif
  2003-02-17 17:30     ` Jeffrey Carter
  0 siblings, 2 replies; 57+ messages in thread
From: Preben Randhol @ 2003-02-17  8:44 UTC (permalink / raw)


Robert C. Leif wrote:
> In principle, the best way to isolate the GUI is to use XForms with XML. One
> can now download an XForms tool that works with Windows,
> http://www.formsplayer.com/. I believe that there are similar tools for
> Linux. The next step is to write the Ada software to interface with XForms.

How do you connect callbacks?


-- 
Preben Randhol ---------------- http://www.pvv.org/~randhol/ --
"Violence is the last refuge of the incompetent", Isaac Asimov



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Re; [OT] Best way to isolate a GUI?
  2003-02-17  7:25   ` Jano
@ 2003-02-17 14:09     ` Bobby D. Bryant
  2003-02-17 21:12       ` Jano
  0 siblings, 1 reply; 57+ messages in thread
From: Bobby D. Bryant @ 2003-02-17 14:09 UTC (permalink / raw)


On Mon, 17 Feb 2003 08:25:06 +0100, Jano wrote:

> Anyways, I not need to be secretive about my project, since is a
> personal one. I'm trying to implement a basic Gnutella servant, just to
> improve my skills in Ada. You see now what's the core and what's the
> GUI...

It's still not clear (to me) from your posts what exactly you're asking.
Are you saying you want to write a client for Gnutella?  And when you say
you want to "isolate the GUI", are you saying that you want a run-time
isolation, or that you want the code separated out so that you can replace
it with a different GUI without having to modify your "core" application
code?

In the latter case the answer is obvious: put your "core" code in one or
more Ada packages and put your GUI code in others.  This will take some
planning ahead, since GUI-based applications tend to be driven by the GUI
and only access the "core" code as callbacks; you will need to think
carefully about what sort of callbacks will be common across various GUIs,
and define your "core" package(s) on the basis of those requirements.

If you want a run-time separation, you still need to give a clearer
explanation of what kind of separation you want.  If you just want to
write a client for Gnutella you will have to write your client to use
whatever communication protocol Gnutella is based on, which is only an Ada
question when it comes down to "how do I implement that?".

-- 
Bobby Bryant
Austin, Texas




^ permalink raw reply	[flat|nested] 57+ messages in thread

* RE: [OT] Best way to isolate a GUI?
  2003-02-17  8:44   ` Preben Randhol
@ 2003-02-17 16:22     ` Robert C. Leif
  2003-02-17 17:30     ` Jeffrey Carter
  1 sibling, 0 replies; 57+ messages in thread
From: Robert C. Leif @ 2003-02-17 16:22 UTC (permalink / raw)
  To: 'comp.lang.ada mail to news gateway'

There are two approaches. 1) Totally ignore the Windows model and create an
Ada environment for XML documents including XForms. Presumably, the
documents would be treated as protected types and managed by Ada tasking.
This model would be very useful for embedded and/or high reliability
systems. 
2) Since the present implementations of XForms are in C++ and Java,
equivalent functionality should be available in Ada. X -Smiles
(http://www.xsmiles.org/) is written in Java and the sources are available
at http://www.xsmiles.org/javadoc/index.html
In both cases the XForms standard (11.2 Submission Options) refers to RFC
2616 HTTP/1.1 (June 1999) (http://www.ietf.org/rfc/rfc2616.txt) which
states:
" 1.4 Overall Operation
   The HTTP protocol is a request/response protocol. A client sends a
   request to the server in the form of a request method, URI, and
   protocol version, followed by a MIME-like message containing request
   modifiers, client information, and possible body content over a
   connection with a server. The server responds with a status line,
   including the message's protocol version and a success or error code,
   followed by a MIME-like message containing server information, entity
   metainformation, and possible entity-body content."
This is essentially an exchange of strings.
Bob Leif

-----Original Message-----
From: Preben Randhol [mailto:randhol+news@pvv.org] 
Sent: Monday, February 17, 2003 12:45 AM
To: comp.lang.ada@ada.eu.org
Subject: Re: [OT] Best way to isolate a GUI?

Robert C. Leif wrote:
> In principle, the best way to isolate the GUI is to use XForms with XML.
One
> can now download an XForms tool that works with Windows,
> http://www.formsplayer.com/. I believe that there are similar tools for
> Linux. The next step is to write the Ada software to interface with
XForms.

How do you connect callbacks?


-- 
Preben Randhol ---------------- http://www.pvv.org/~randhol/ --
"Violence is the last refuge of the incompetent", Isaac Asimov




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17  8:44   ` Preben Randhol
  2003-02-17 16:22     ` Robert C. Leif
@ 2003-02-17 17:30     ` Jeffrey Carter
  2003-02-17 17:54       ` Warren W. Gay VE3WWG
  1 sibling, 1 reply; 57+ messages in thread
From: Jeffrey Carter @ 2003-02-17 17:30 UTC (permalink / raw)


Preben Randhol wrote:
> 
> How do you connect callbacks?

Callbacks are an excellent example of a tool's limitations affecting the 
users' way of thinking (everything looking like a nail if you only have 
a hammer).

Windowing systems result in inherently concurrent processing: the code 
of the windowing system may be dealing with user interaction while the 
application program is doing something else. How do you deal with this 
concurrency? When your thinking is constrained by the limitiations of C, 
you do it by task inversion: You eliminate the concurrency. Only the 
windowing code is running; application code is called by the windowing 
code. How can the windowing code call the application? By having the 
application register callbacks with the windowing system before handing 
control of the program over to the windowing system. In C, where nothing 
is checked and you can call any address, this is easy to do.

If one were to design a windowing system with thinking expanded by the 
use of a language with high-level concurrency features (like, maybe, 
Ada?), I can't imagine anyone choosing this design. I would think you'd 
want to associate a concurrent event queue for each window. A task in 
the application would deal with the events for its window. It could 
block on the queue to do nothing except respond to events, or it could 
poll the queue periodically if it has other things to do as well.

While I like many things about GtkAda, one of the things I dislike about 
it is that it hasn't abstracted away this C feature of the GUI. As a 
result, it's harder to use tasking with GtkAda than it should be. CLAW 
and JEWL, for example, have abstracted callbacks away to different 
extents. JEWL effectively implements the concurrent event queue 
abstraction on top of Windows.

-- 
Jeff Carter
"Why don't you bore a hole in yourself and let the sap run out?"
Horse Feathers




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17 17:30     ` Jeffrey Carter
@ 2003-02-17 17:54       ` Warren W. Gay VE3WWG
  2003-02-17 19:06         ` Randy Brukardt
                           ` (3 more replies)
  0 siblings, 4 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-17 17:54 UTC (permalink / raw)


Jeffrey Carter wrote:
> Preben Randhol wrote:
>> How do you connect callbacks?
> 
> Callbacks are an excellent example of a tool's limitations affecting the 
> users' way of thinking (everything looking like a nail if you only have 
> a hammer).
> 
...
> If one were to design a windowing system with thinking expanded by the 
> use of a language with high-level concurrency features (like, maybe, 
> Ada?), I can't imagine anyone choosing this design. 

I find that the "callback idea" works ok if you design it in a
clean way (in Ada95 terms). I agree that the C method of hammering
things from void pointers into client data and widget data, is ghastly
at best.  A generic could deal with the client data aspect.

For input and output callback arguments, I use a discriminated record,
which then allows Ada95 checks on record members according to the event
type (ie. the record variation). This is something I wish GtkAda would
use.

> I would think you'd 
> want to associate a concurrent event queue for each window. A task in 
> the application would deal with the events for its window. It could 
> block on the queue to do nothing except respond to events, or it could 
> poll the queue periodically if it has other things to do as well.

This sounds conceptually nice, but it could prove to have practical
problems (I need to think about this more, myself). Thinking in terms
of an X11/MOTIF application, where there can be hundreds of windows within
windows to implement widgets on a form, this translates to hundreds
(if not more) of tasks. This smells a lot like overkill upon first
blush at least.

Additionally, where the application wants access to one event, it would
need to provide an entire task, and then have null handlers for all
the events it was not interested in (I think).  I think I'd need
to prototype this to get a better feel for this.

It might be easier to start with a tagged object, where methods can
be inherited and overriden instead. That way all events can just
do nothing, while you override the events you are interested in.
But this takes us back to a model similar to callbacks anyways, but
instead of registering a callback, you register a tagged record
to receive callbacks.

> While I like many things about GtkAda, one of the things I dislike about 
> it is that it hasn't abstracted away this C feature of the GUI. As a 
> result, it's harder to use tasking with GtkAda than it should be. CLAW 
> and JEWL, for example, have abstracted callbacks away to different 
> extents. JEWL effectively implements the concurrent event queue 
> abstraction on top of Windows.

I can't speak for CLAW, and the one shortcoming I see in JEWL is that
you cannot get "focus events". But the last time I played with GtkAda
I didn't like the callback structures either. They were too prone to
error, because of the data marshalling issues, IIRC.

I would much rather that callbacks used discriminated records that
matched the event type. Then everything compiles well, and is
thoroughly checked, admitedly, some of it at run time. Most of all,
the callback becomes a well documented interface, and is simple to
code for and understand.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17 17:54       ` Warren W. Gay VE3WWG
@ 2003-02-17 19:06         ` Randy Brukardt
  2003-02-18  3:15           ` Warren W. Gay VE3WWG
  2003-02-17 19:31         ` tmoran
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 57+ messages in thread
From: Randy Brukardt @ 2003-02-17 19:06 UTC (permalink / raw)


Warren W. Gay VE3WWG wrote in message <3E5121BD.4010200@cogeco.ca>...
>For input and output callback arguments, I use a discriminated record,
>which then allows Ada95 checks on record members according to the event
>type (ie. the record variation). This is something I wish GtkAda would
>use.


That doesn't work well if you have callbacks which are evolving (as most
real-world GUIs are). Adding a new variant to a record can break
existing code (think aggregates, think name conflicts), and will require
recompiling everything in sight.

What we did with Claw is define a tagged type to hold the client data.
Then an extension of it can hold any possible callback's data, including
those that aren't defined yet. The data parameter is then a class-wide
object of the tagged type.

The checking, like the variant record's, is at runtime (because you'll
need an explicit conversion to the appropriate type in order to read the
components). But the checking is (usually) cheaper, because it occurs in
only one place, and it requires less code if the variant is at all
complex.

               Randy.





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17 17:54       ` Warren W. Gay VE3WWG
  2003-02-17 19:06         ` Randy Brukardt
@ 2003-02-17 19:31         ` tmoran
  2003-02-18  1:37         ` Jeffrey Carter
  2003-02-18 13:29         ` Marin David Condic
  3 siblings, 0 replies; 57+ messages in thread
From: tmoran @ 2003-02-17 19:31 UTC (permalink / raw)


> > Callbacks are an excellent example of a tool's limitations affecting the
> > users' way of thinking (everything looking like a nail if you only have
> > a hammer).
>...
> I can't speak for CLAW,
  Claw handles window event callbacks by calling tagged object procedures,
which may be overridden by the app program.  It's all type-checked etc
Ada.  It's like writing all your code inside interrupt handlers.  But an
app that isn't basically a set of event responders can be done differently.
  One of the Claw demo programs, Bigjob, has a main task that just does a
(dummy) big computation, and a separate windows' event handler task.  The
windows routines put user command stuff into a message and the computation
task periodically checks there to see if it needs to modify its computation.
Similarly, the computation task periodically puts results in a status
record.  The window task inspects that and updates the display as needed.
In the Bigjob example, if the main task wants to force an immediate screen
update, it simply invalidates the window, which forces a redraw, which
will use the updated status info.



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 14:49 ` Victor Porton
@ 2003-02-17 20:52   ` Jano
  0 siblings, 0 replies; 57+ messages in thread
From: Jano @ 2003-02-17 20:52 UTC (permalink / raw)


En el mensaje <E18kQ6a-0005fE-00@porton.narod.ru>, porton@ex-code.com 
dice...
> In article <MPG.18b98425db7e9aef989698@news.cis.dfn.de>,
> 	Jano <402450@cepsz.unizar.es> writes:
> > as for my (lately) frequent questions, you may be aware I'm starting a 
> > new project in Ada. Well, the matter is that I want the core 
> > functionality to be isolated from the GUI. And that's the question: 
> > how's the best mean to do that.
> > 
> > I've thought the following:
> > 
> > 2) Use sockets to communicate the two processes.
> > 2.a) Use regular Ada streams to pass data types.
> > 2.b) Use some other protocol, for example [compressed] XML.
> 
> Ada has partitions for this! (See RM.)

I thought of this after posting, but I'm really ignorant about the 
distributed annex. Shall check, of course. 

-- 
-------------------------
Jano
402450[at]cepsz.unizar.es
-------------------------



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Re; [OT] Best way to isolate a GUI?
  2003-02-17 14:09     ` Bobby D. Bryant
@ 2003-02-17 21:12       ` Jano
  2003-02-18  7:24         ` Jean-Pierre Rosen
  0 siblings, 1 reply; 57+ messages in thread
From: Jano @ 2003-02-17 21:12 UTC (permalink / raw)


En el mensaje <pan.2003.02.17.14.09.34.88722@mail.utexas.edu>, 
bdbryant@mail.utexas.edu dice...
> On Mon, 17 Feb 2003 08:25:06 +0100, Jano wrote:
> 
> > Anyways, I not need to be secretive about my project, since is a
> > personal one. I'm trying to implement a basic Gnutella servant, just to
> > improve my skills in Ada. You see now what's the core and what's the
> > GUI...

> If you want a run-time separation, you still need to give a clearer
> explanation of what kind of separation you want.  If you just want to
> write a client for Gnutella you will have to write your client to use
> whatever communication protocol Gnutella is based on, which is only an Ada
> question when it comes down to "how do I implement that?".

I want total isolation between core and GUI. Really, that it's going to 
be a Gnutella servant is not relevant except for background. For total 
isolation I mean that the core could run without a GUI. I.e., the GUI 
code is not necessary at compile time. Indeed, a Gnutella servant 
doesn't need the GUI except for feedback and getting new searches from 
the user. That could be accomplished with a single input box. 

I'll detail my first thought, so you can see what I want and you can 
reduce then my idea to pieces ;-).

I was thinking of using a proccess for the core, and none..many 
proccesses as GUI. To accomplish that:

a) The core opens a listening socket.
b) Spawn a child for every new connected "thing" (GUI) to the listening 
socket.
c) These new connections (streams) are used by the core to notify the 
listener (client in this context) about events, to pass data, or by the 
GUIs to request specific data it want to display/refresh.

The communication protocol could be anything I want (hence the 
suggestion of XML). I need "only" :) to define a proper protocol (but my 
first idea is, given that I expect to use heavily XML for config files 
and persistence of objects, simply pass the objects as its XML 
representation and a bunch of requesting/notifying words).

One GUI proccess could be a web server (AWS), or could be a GtkAda GUI, 
or whatever. But that's the point.

Thoughts?

The only example that comes to my mind like that is the WinGate 
router/NAT software. It's a NT service that listens in 808 for the GUI, 
which is a regular Windows app.

Oh, and Audiogalaxy Satellite was also using that approach.

But I'm only beginning to get at the other suggestions.

-- 
-------------------------
Jano
402450[at]cepsz.unizar.es
-------------------------



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17 17:54       ` Warren W. Gay VE3WWG
  2003-02-17 19:06         ` Randy Brukardt
  2003-02-17 19:31         ` tmoran
@ 2003-02-18  1:37         ` Jeffrey Carter
  2003-02-18  3:39           ` Warren W. Gay VE3WWG
  2003-02-18 23:36           ` Randy Brukardt
  2003-02-18 13:29         ` Marin David Condic
  3 siblings, 2 replies; 57+ messages in thread
From: Jeffrey Carter @ 2003-02-18  1:37 UTC (permalink / raw)


Warren W. Gay VE3WWG wrote:
> 
> This sounds conceptually nice, but it could prove to have practical
> problems (I need to think about this more, myself). Thinking in terms
> of an X11/MOTIF application, where there can be hundreds of windows within
> windows to implement widgets on a form, this translates to hundreds
> (if not more) of tasks. This smells a lot like overkill upon first
> blush at least.

I wouldn't think you'd want a queue for every widget. I'd think one per 
top-level window would be about right. The events in the queue would 
have to identify the widget that generated them. In some cases you'd 
have a task for every window, while in others one task might handle the 
events from several windows. It's a question of what the problem's 
concurrency needs are, not what the windowing system forces on you. You 
wouldn't be forced to declare any tasks, if tasking's not appropriate to 
the problem.

> 
> Additionally, where the application wants access to one event, it would
> need to provide an entire task, and then have null handlers for all
> the events it was not interested in (I think).  I think I'd need
> to prototype this to get a better feel for this.

There can be an awful lot of different events from a window. I would 
think you could tell the system what events to report and which to 
ignore, with a default set that is frequently useful. Then, if you're 
only interested in the close event from a window, it won't send you 
anything else.

> 
> It might be easier to start with a tagged object, where methods can
> be inherited and overriden instead. That way all events can just
> do nothing, while you override the events you are interested in.
> But this takes us back to a model similar to callbacks anyways, but
> instead of registering a callback, you register a tagged record
> to receive callbacks.

This is the approach taken by CLAW. A widget is represented by a tagged 
type, with primitive operations that are called automatically when 
certain events occur. There are default versions of these operations. To 
create a widget with specific behavior, you have to extend the type and 
override the appropriate operations. This can be useful when you want to 
have data associated with a widget, as you can define the data as part 
of the extension, give the widget values when you create it, and check 
the values in the operations. But when all you want is to define the 
application's behavior when the user clicks a button, it seems like 
overkill. Consider a window with lots of buttons, different behavior 
when each button is clicked, and little or nothing else in the way of 
user input. This calls for many extensions and many overridings of the 
appropriate operation. It differs from callbacks in not requiring 
operations to be registered with the windowing system, but similar in 
that the windowing system controls your application.

> I can't speak for CLAW, and the one shortcoming I see in JEWL is that
> you cannot get "focus events".

JEWL is deliberately a simple system, and the lack of some features is 
the price of that simplicity. The concept of the application actively 
requesting events from the windowing system is one that could be applied 
to a more complex windowing system.

Nothing's perfect, and GtkAda and CLAW represent a lot of good work. 
JEWL is very good, too, for its application area of providing a simple 
windowing system for beginners.

-- 
Jeff Carter
"My name is Jim, but most people call me ... Jim."
Blazing Saddles




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17 19:06         ` Randy Brukardt
@ 2003-02-18  3:15           ` Warren W. Gay VE3WWG
  2003-02-18 16:14             ` Robert C. Leif
  2003-02-18 18:10             ` Randy Brukardt
  0 siblings, 2 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-18  3:15 UTC (permalink / raw)


Randy Brukardt wrote:
> Warren W. Gay VE3WWG wrote in message <3E5121BD.4010200@cogeco.ca>...
> 
>>For input and output callback arguments, I use a discriminated record,
>>which then allows Ada95 checks on record members according to the event
>>type (ie. the record variation). This is something I wish GtkAda would
>>use.
> 
> That doesn't work well if you have callbacks which are evolving (as most
> real-world GUIs are). Adding a new variant to a record can break
> existing code (think aggregates, think name conflicts), and will require
> recompiling everything in sight.

I don't find this a particularly good argument. I want the code to break
if I change the callback requirements, even if just for one event.
Any structure changes are all localized to the variant
record, so it is very easy to locate conflicts (or simply let the compiler
do it for you). Of course not all variant record violations can be
detected at runtime (some can however).

As far as "recompiling everything in sight", I feel this is not a good
reason to avoid it. If a recompile is necessary (which GNAT _can_ determine),
then let it compile away. This is an automatic process.

Reluctance to recompile suggests that your goals are not in sync
with the end user's--  ;-)

The end goal, IMHO, is to produce a library that provides the best interface
to the user; not to be convenient to the library developer ;-)

The X11 software (a real world GUI, BTW) uses a finite number of members
in the XEvent union (albiet in C, and certainly inferior to any Ada95
variant record).  This model has been well proven and works well. The
bonus is, that if you insist on a very general structure, this too can
be accomodated in a variant record with a system.address or some such
kludge. But at least that kludge is optional, and perhaps temporary as
your GUI evolves to perfection.

So I am still unconvinced that variant records are not useful
in a callback context.  In fact, apart from one concession (below),
I think they work rather well in the "traditional callback" scheme
of things.

Whether or not the "traditional callback" is the best way to do it, is
yet another question, and open to debate.

> What we did with Claw is define a tagged type to hold the client data.
> Then an extension of it can hold any possible callback's data, including
> those that aren't defined yet. The data parameter is then a class-wide
> object of the tagged type.

User data is indeed a challenge. I took a slightly different approach
to this in a top secret ;) project that I am currently working on.
I stored the system.address of the user data in the application
context object, which is passed to every callback. Using the system.address
is bad for many reasons, but I felt this one compromise was better than
several others I would otherwise be forced to consider (the only real
exposure is if the application should free its copy of the user data
for some odd reason).

A generic function then takes as input a parameter (the application context)
provided by the callback. It then safely returns a pointer to the user
data for application callback use.

> The checking, like the variant record's, is at runtime (because you'll
> need an explicit conversion to the appropriate type in order to read the
> components). But the checking is (usually) cheaper, because it occurs in
> only one place, and it requires less code if the variant is at all
> complex.
>                Randy.

This point I might agree with you on (although a bit skeptical). If you
replace a complex variant record with a complex hierarchy of tagged
records, then I would think that there is still a significant amount
of chasing pointers etc. behind the scenes in the tagged record case.

If you have only a few instances of "case", then even with many "whens",
then I don't think the overhead needs to be extreme with the appropriate
optimizing compiler technology. I'll concede however that it might
be worse than the tagged approach.. but how much different it is, would
be an interesting study.  Maybe a good topic for a paper ;-)

It is my opinion however, that the difference is small enough to ignore
for general purpose computing purposes.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18  1:37         ` Jeffrey Carter
@ 2003-02-18  3:39           ` Warren W. Gay VE3WWG
  2003-02-18 23:36           ` Randy Brukardt
  1 sibling, 0 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-18  3:39 UTC (permalink / raw)


Jeffrey Carter wrote:
> Warren W. Gay VE3WWG wrote:
>> This sounds conceptually nice, but it could prove to have practical
>> problems (I need to think about this more, myself). Thinking in terms
>> of an X11/MOTIF application, where there can be hundreds of windows 
>> within
>> windows to implement widgets on a form, this translates to hundreds
>> (if not more) of tasks. This smells a lot like overkill upon first
>> blush at least.
> 
> I wouldn't think you'd want a queue for every widget. I'd think one per 
> top-level window would be about right. The events in the queue would 
> have to identify the widget that generated them. In some cases you'd 
> have a task for every window, while in others one task might handle the 
> events from several windows. It's a question of what the problem's 
> concurrency needs are, not what the windowing system forces on you. You 
> wouldn't be forced to declare any tasks, if tasking's not appropriate to 
> the problem.

I see two problems developing with this:

1. deciding how to segregate the work between which widgets and tasks
    (ie. the infrastructure becomes more complicated because you now must
     decide which windows get their own tasks and which ones don't).

2. Each queue must contain a big case statement for all of the widget
    cases it must separate the code out for.  The callback approach only
    has to call all registered callbacks for _that_ widget, on its callback
    list. The callback is already specific to the widget, so no big case
    statement is required.

    This queue also suffers from the problem that you would need to code this
    ahead of time (you must plan a when clause for a particular widget in
    a queue's event processing section).  This makes it more difficult to
    handle dynamically created widgets (like popups), because you would then
    have to plan for it in the code. Whereas the callback is already there
    for any created widget.

Since GUIs often have widgets created and destroyed on the fly (like a message
box), I can't see this being very practical. The fact that I don't see any
GUI framework structured this way yet, suggests to me that there are reasons
why this is not practical. However, this is not to say that nobody should
try it ;-)

>> Additionally, where the application wants access to one event, it would
>> need to provide an entire task, and then have null handlers for all
>> the events it was not interested in (I think).  I think I'd need
>> to prototype this to get a better feel for this.
> 
> There can be an awful lot of different events from a window. I would 
> think you could tell the system what events to report and which to 
> ignore, with a default set that is frequently useful. Then, if you're 
> only interested in the close event from a window, it won't send you 
> anything else.

It is easier to call a callback list than to mainain a list of what
events to pay attention to or not, IMHO. It is certainly conceptually
cleaner.

>> It might be easier to start with a tagged object, where methods can
>> be inherited and overriden instead. That way all events can just
>> do nothing, while you override the events you are interested in.
>> But this takes us back to a model similar to callbacks anyways, but
>> instead of registering a callback, you register a tagged record
>> to receive callbacks.
> 
> This is the approach taken by CLAW. A widget is represented by a tagged 
> type, with primitive operations that are called automatically when 
> certain events occur. There are default versions of these operations. To 
> create a widget with specific behavior, you have to extend the type and 
> override the appropriate operations. 

Definitely a useful application of tagged records.

>> I can't speak for CLAW, and the one shortcoming I see in JEWL is that
>> you cannot get "focus events".
> 
> JEWL is deliberately a simple system, and the lack of some features is 
> the price of that simplicity. The concept of the application actively 
> requesting events from the windowing system is one that could be applied 
> to a more complex windowing system.

I was not being "critical" of JEWL, but merely pointing out that it does
have "limitations". This was one I noticed right away when looking to see
if I could make use of it.  Certainly for its intended use in teaching, it
does a wonderful job with its simple interface.

> Nothing's perfect, and GtkAda and CLAW represent a lot of good work. 
> JEWL is very good, too, for its application area of providing a simple 
> windowing system for beginners.

I don't think anyone was trashing these efforts. It is good to discuss
the strengths and weaknesses of the various tools from time to time.
Even mine ;-)  As software engineers, I think we can handle some
constructive remarks from time to time. 8-O

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Re; [OT] Best way to isolate a GUI?
  2003-02-17 21:12       ` Jano
@ 2003-02-18  7:24         ` Jean-Pierre Rosen
  0 siblings, 0 replies; 57+ messages in thread
From: Jean-Pierre Rosen @ 2003-02-18  7:24 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1020 bytes --]


"Jano" <402450@cepsz.unizar.es> a �crit dans le message de news: MPG.18bb6ea1d4e7753f98969c@News.CIS.DFN.DE...
> I want total isolation between core and GUI. Really, that it's going to
> be a Gnutella servant is not relevant except for background. For total
> isolation I mean that the core could run without a GUI. I.e., the GUI
> code is not necessary at compile time. Indeed, a Gnutella servant
> doesn't need the GUI except for feedback and getting new searches from
> the user. That could be accomplished with a single input box.
>
A solution that I have used quite often in that kind of occasion:
1) make your application command line oriented only (read from standard input, output to standard output)
2) run it from Tcl and let Tcl send the commands.
3) (optional) integrate the Tcl part into the program with Tash, if you don't want Tcl to be apparent.


--
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
                   ` (6 preceding siblings ...)
  2003-02-17  0:57 ` Re; " tmoran
@ 2003-02-18 13:08 ` Marin David Condic
  7 siblings, 0 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-18 13:08 UTC (permalink / raw)


It depends on just how isolated you want to go. When I've built things with
GtkAda, I've wanted the GUI to be unbundled from the "real" app so I'd have
an easy time changing front ends if that seemed to be necessary. To do that,
I just create an isolation package that responds to the callbacks & sends
data to the GUI - the rest of the app is one or more objects that do all the
computational work.

If you want to swap out front-ends at will without changing any code, I can
suggest what happens in various military systems I've worked on. You pick
some standard communications link and carefully define a message catalog
that specifies the exact format and content of the communications to run
between the subsystems. (A command/response protocol is usually simplest,
but not always possible depending on how many different things are
communicating & what has to happen) This lets you substitute *anything* at
the front end so long as it can properly produce & respond to the message
catalog.

It would be good for Ada to have some kind of conventional GUI and maybe
this suggests a possible answer: Define a message catalog and Ada interface
to it that would allow adaptation to any number of possible GUI
environments. Most GUI things tend to work on the concept of "messages"
anyway, so its hardly a big stretch. I think there are some things that
would have to be overcome (like lack of certainty about representation with
stream operations or various problems with tagged records - things that
might be overcome by using some kind of text based protocol like XML - which
has its own downsides). A little creativity might result in a clean, simple
way of getting Ada a "standard" GUI without killing any existing GUI
builders.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================
Jano <402450@cepsz.unizar.es> wrote in message
news:MPG.18b98425db7e9aef989698@News.CIS.DFN.DE...
> Hello,
>
> as for my (lately) frequent questions, you may be aware I'm starting a
> new project in Ada. Well, the matter is that I want the core
> functionality to be isolated from the GUI. And that's the question:
> how's the best mean to do that.
>
> I've thought the following:
>
> 1) Use AWS and let any browser do the rendering. That's not really
> isolating the GUI, because all the generating code would be inside the
> core (unless I also apply):
>
> 2) Use sockets to communicate the two processes.
> 2.a) Use regular Ada streams to pass data types.
> 2.b) Use some other protocol, for example [compressed] XML.
>
> 3) Your sugestions welcome.
>
> I would want that the isolation be such any kind of GUI can be build on
> top. Maybe even made two of them run concurrently. For example, web
> reports via AWS and a control GUI with native look.
>
> Any have prior experience? Some successful example on the wild to check?
>
> Thanks in advance,
>
> --
> -------------------------
> Jano
> 402450[at]cepsz.unizar.es
> -------------------------





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-17 17:54       ` Warren W. Gay VE3WWG
                           ` (2 preceding siblings ...)
  2003-02-18  1:37         ` Jeffrey Carter
@ 2003-02-18 13:29         ` Marin David Condic
  2003-02-18 18:01           ` Warren W. Gay VE3WWG
  3 siblings, 1 reply; 57+ messages in thread
From: Marin David Condic @ 2003-02-18 13:29 UTC (permalink / raw)


You could get it down to one task if you basically go to some kind of
message protocol. Build a wrapper around something like GtkAda that deals
with the callbacks, etc. That builds up messages that are queued for the
app. The app pulls them out of the queue as it is ready for them and queues
up responses for the GUI. That doesn't fix Motif & GtkAda from being a C-ish
thing, but it hides all the C-ishness in the wrapper. You'd also get a means
by which you could have a portable GUI interface by building a similar
wrapper around Claw or anything else that gets dreampt up.

In the perfect world where there is an ongoing Ada Operating System project,
this might be a great design for the interface to the GUI. Asynchronous
message traffic via any number of communication mechanisms.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E5121BD.4010200@cogeco.ca...
>
> This sounds conceptually nice, but it could prove to have practical
> problems (I need to think about this more, myself). Thinking in terms
> of an X11/MOTIF application, where there can be hundreds of windows within
> windows to implement widgets on a form, this translates to hundreds
> (if not more) of tasks. This smells a lot like overkill upon first
> blush at least.
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* RE: [OT] Best way to isolate a GUI?
  2003-02-18  3:15           ` Warren W. Gay VE3WWG
@ 2003-02-18 16:14             ` Robert C. Leif
  2003-02-18 18:10             ` Randy Brukardt
  1 sibling, 0 replies; 57+ messages in thread
From: Robert C. Leif @ 2003-02-18 16:14 UTC (permalink / raw)
  To: 'comp.lang.ada mail to news gateway'

Although, I can definitely see the utility of using a tagged type for a
screen, in the XML world a significant part of that screen is data. At
SIGAda 03, there was a discussion of creating tagged protected types. Would
this be the best solution? If so, how much work would it be for the compiler
vendors implement tagged protected types?
Bob Leif




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 13:29         ` Marin David Condic
@ 2003-02-18 18:01           ` Warren W. Gay VE3WWG
  2003-02-19 13:06             ` Marin David Condic
  0 siblings, 1 reply; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-18 18:01 UTC (permalink / raw)


Marin David Condic wrote:
> You could get it down to one task if you basically go to some kind of
> message protocol. Build a wrapper around something like GtkAda that deals
> with the callbacks, etc. That builds up messages that are queued for the
> app. The app pulls them out of the queue as it is ready for them and queues
> up responses for the GUI. That doesn't fix Motif & GtkAda from being a C-ish
> thing, but it hides all the C-ishness in the wrapper. You'd also get a means
> by which you could have a portable GUI interface by building a similar
> wrapper around Claw or anything else that gets dreampt up.

But this still suffers from one problem: Each queue in your task
would then have a monster case statement to split out the work
according to the widget that is receiving the event. Compare this
to the registered callback where only the interested widget for
the event gets the callback. No big case statement required for
event, or widget.

Don't get me wrong.. I like the idea of queues and tasks. But this seems
a clumsy thing beside a callback.

> In the perfect world where there is an ongoing Ada Operating System project,
> this might be a great design for the interface to the GUI. Asynchronous
> message traffic via any number of communication mechanisms.
> 
> MDC

There may be a better model to use than a callback. I just don't seeing
tasks, or tasks alone being it yet.  If tasks are part of the solution, then
you'd have to combine it with a Booch map (say) to eliminate those case statements,
and to handle the dynamic creation and destruction of widgets that need to hook
into events dynamically.

But then after using a map, you might wind up in the end just doing a dispatch
in callback fashion anyway.. ending up with the same end result.

So I dunno.. I remain unconvinced. ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18  3:15           ` Warren W. Gay VE3WWG
  2003-02-18 16:14             ` Robert C. Leif
@ 2003-02-18 18:10             ` Randy Brukardt
  2003-02-18 21:12               ` Warren W. Gay VE3WWG
  1 sibling, 1 reply; 57+ messages in thread
From: Randy Brukardt @ 2003-02-18 18:10 UTC (permalink / raw)



Warren W. Gay VE3WWG wrote in message <3E51A55A.3000101@cogeco.ca>...
>Randy Brukardt wrote:
>> Warren W. Gay VE3WWG wrote in message <3E5121BD.4010200@cogeco.ca>...
>>
>>>For input and output callback arguments, I use a discriminated
record,
>>>which then allows Ada95 checks on record members according to the
event
>>>type (ie. the record variation). This is something I wish GtkAda
would
>>>use.
>>
>> That doesn't work well if you have callbacks which are evolving (as
most
>> real-world GUIs are). Adding a new variant to a record can break
>> existing code (think aggregates, think name conflicts), and will
require
>> recompiling everything in sight.
>
>I don't find this a particularly good argument. I want the code to
break
>if I change the callback requirements, even if just for one event.
>Any structure changes are all localized to the variant
>record, so it is very easy to locate conflicts (or simply let the
compiler
>do it for you). Of course not all variant record violations can be
>detected at runtime (some can however).
>
>As far as "recompiling everything in sight", I feel this is not a good
>reason to avoid it. If a recompile is necessary (which GNAT _can_
determine),
>then let it compile away. This is an automatic process.
>
>Reluctance to recompile suggests that your goals are not in sync
>with the end user's--  ;-)


Most end users that I'm familar with don't want to have to rewrite all
of their programs because we've provided an updated version of the
interface with a few new features. That requires the interface to change
as little as possible. Even adding a parameter can cause problems with
extensions of a type. Adding visible components (which breaks all
aggregates) is simply not acceptable.

>The end goal, IMHO, is to produce a library that provides the best
interface
>to the user; not to be convenient to the library developer ;-)


There is nothing "convenient to the library developer" about either of
these "solutions". The best solution is to not have the problem in the
first place. Thus, we use dedicated action routines (callbacks) whenever
possible. The only place that we use any sort of variable data is in the
lower-level Notification interface, and that's because Microsoft gives
us no choice.

Note that the notification interface in Windows is defined as a set of
overlayed records, using which ever one is appropriate for the current
message. There is no "variant" and certainly no discriminant. And each
new thing Microsoft adds creates a bunch more of these.

The big problem with the variant interface is that everything has to be
defined in one place. That's usually not practical. The notification
data includes various data types specific to each of the types of
controls. If we had to put all of that in the spec. of the Claw root
package, we'd more than double its size (and its already 5000 lines).

We recently completed a project eliminating as much unused stuff from
user programs as possible. If we had used a variant solution, there
would be no possibility of that, as every possible control would have to
be reflected in that variant. Since we used a tagged type, we don't have
to drag in Tree Views unless the user actually withs Claw.Tree_View.
(That was happening for another reason, and the internal restructuring
eliminated that.) That cut the average size of Claw programs by 500K.

>The X11 software (a real world GUI, BTW) uses a finite number of
members
>in the XEvent union (albiet in C, and certainly inferior to any Ada95
>variant record).  This model has been well proven and works well. The
>bonus is, that if you insist on a very general structure, this too can
>be accomodated in a variant record with a system.address or some such
>kludge. But at least that kludge is optional, and perhaps temporary as
>your GUI evolves to perfection.


If you're mapping an existing union, you're way ahead of the game. But
that's a pretty limited GUI (and calling X11 a GUI is a stretch).
Windows doesn't work this way, and I doubt that many of the higher level
GUIs built on top of X11 do, either.

                 Randy.





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 18:10             ` Randy Brukardt
@ 2003-02-18 21:12               ` Warren W. Gay VE3WWG
  2003-02-18 23:20                 ` Randy Brukardt
  2003-02-19 12:49                 ` Marin David Condic
  0 siblings, 2 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-18 21:12 UTC (permalink / raw)


Randy Brukardt wrote:
> Warren W. Gay VE3WWG wrote in message <3E51A55A.3000101@cogeco.ca>...
>>Randy Brukardt wrote:
>>>Warren W. Gay VE3WWG wrote in message <3E5121BD.4010200@cogeco.ca>...
>>>>For input and output callback arguments, I use a discriminated record,
>>>>which then allows Ada95 checks on record members according to the event
>>>>type (ie. the record variation). This is something I wish GtkAda would
>>>>use.
>>>That doesn't work well if you have callbacks which are evolving (as
> most real-world GUIs are). Adding a new variant to a record can break
>>>existing code (think aggregates, think name conflicts), and will require
>>>recompiling everything in sight.
>>
>>I don't find this a particularly good argument. I want the code to break
>>if I change the callback requirements, even if just for one event.
>>Any structure changes are all localized to the variant
>>record, so it is very easy to locate conflicts (or simply let the compiler
>>do it for you). Of course not all variant record violations can be
>>detected at runtime (some can however).
>>
>>As far as "recompiling everything in sight", I feel this is not a good
>>reason to avoid it. If a recompile is necessary (which GNAT _can_ determine),
>>then let it compile away. This is an automatic process.
>>
>>Reluctance to recompile suggests that your goals are not in sync
>>with the end user's--  ;-)
> 
> Most end users that I'm familar with don't want to have to rewrite all
> of their programs because we've provided an updated version of the
> interface with a few new features. 

New features should not be radically changing callbacks in the first
place. Some changes can be made forward compatible, and others might
just make more event data available. No problem.

> That requires the interface to change
> as little as possible. Even adding a parameter can cause problems with
> extensions of a type. Adding visible components (which breaks all
> aggregates) is simply not acceptable.

I would think the assigning of aggregates to a callback should
be rather rare, since it is the library producing the callback
and the variant record. The callback code is merely "using" the
variant record -- not creating it.

>>The end goal, IMHO, is to produce a library that provides the best interface
>>to the user; not to be convenient to the library developer ;-)
> 
> There is nothing "convenient to the library developer" about either of
> these "solutions". The best solution is to not have the problem in the
> first place. Thus, we use dedicated action routines (callbacks) whenever
> possible. 

All I am saying is that the callback "event data" can be provided by
a variant record, that is customized to the event. This is what the X11
library does (union), and the model works well.

> The only place that we use any sort of variable data is in the
> lower-level Notification interface, and that's because Microsoft gives
> us no choice.

Well, this may in fact be part of the reason you made your choice.
Interfacing to Microsoft.. say no more ;-)

> Note that the notification interface in Windows is defined as a set of
> overlayed records, using which ever one is appropriate for the current
> message. There is no "variant" and certainly no discriminant. And each
> new thing Microsoft adds creates a bunch more of these.

And yes, that is the way _Microsoft_ did it. I am just suggesting that
in Ada based "systems", it need not be that way. The fact that Microsoft
does it one way, in C terms, does not influence what is good and proper
in an Ada environment. It only determines the beast you must interface
with.

> The big problem with the variant interface is that everything has to be
> defined in one place. 

Why is that a problem? XEvent does this too. So?

> That's usually not practical. The notification
> data includes various data types specific to each of the types of
> controls. 

OK, I can see that you might have some package interdependency
issues, depending on the data _types_ being used. I do believe
however, that careful planning can avoid these problems.

> If we had to put all of that in the spec. of the Claw root
> package, we'd more than double its size (and its already 5000 lines).

So? What problem? Longer compile times? Is that what we're worried
about? It may be a consideration, but not necessarily a
deciding factor.

> We recently completed a project eliminating as much unused stuff from
> user programs as possible. 

And that is fine and good. Hopefully all library writers do that.

> If we had used a variant solution, there
> would be no possibility of that, as every possible control would have to
> be reflected in that variant. 

This is patently false.

I don't believe that just because a variant record is used that this
eliminates the possibility of a cleanup.  The reason is this: you only
carry _EVENT_ data in this variant record -- not widget internal data.
This event data can be used to communicate with many widget callbacks.

Perhaps you misunderstand what I am suggesting here -- I am not
suggesting widgets in a variant record. Oh, no! Only _event_ data.

> Since we used a tagged type, we don't have
> to drag in Tree Views unless the user actually withs Claw.Tree_View.
> (That was happening for another reason, and the internal restructuring
> eliminated that.) That cut the average size of Claw programs by 500K.

Look at the way XEvents is defined. It does not define a member for each
widget. It defines a view for each _event_ type. The members correspond to
needs of the _event_ _communication_.  Nothing you have said has invalidated
this approach.

>>The X11 software (a real world GUI, BTW) uses a finite number of members
>>in the XEvent union (albiet in C, and certainly inferior to any Ada95
>>variant record).  This model has been well proven and works well. The
>>bonus is, that if you insist on a very general structure, this too can
>>be accomodated in a variant record with a system.address or some such
>>kludge. But at least that kludge is optional, and perhaps temporary as
>>your GUI evolves to perfection.
> 
> If you're mapping an existing union, you're way ahead of the game. 

I'm not mapping an existing union. It is in the discussion as point
of reference.

> But
> that's a pretty limited GUI (and calling X11 a GUI is a stretch).

Um, MOTIF, which is used UNIX-wide, is entirely built upon X11.
Not to mention that Gtk also builds upon X11 in the environments
that require it. The X intrinsics build upon X11 to provide the
widget foundation and callbacks, that other widget sets in X use
(like MOTIF/LessTif).  All of these layers use callbacks and
event data. If this aint a serious GUI, then tell me why
the LessTif team has taken several years to duplicate MOTIF 2? ;-)
It is, and continues to be.

> Windows doesn't work this way, and I doubt that many of the higher level
> GUIs built on top of X11 do, either.
> 
>                  Randy.

Windows may be the mess that it is for several reasons. If you have
to adapt to it fine.
All I have been saying all along though, is that
it _need_ _not_ be that way in a new Ada based GUI library.
You have practical reasons for the choices
you have made, and I'll accept that.

But my point has always been in this
thread is that there has been no good reason given that event data
cannot be provided in a callback parameter as a variant record.

You brought some interesting points to the discussion, but none
that would convince me that variant records are unsuitable for
the job. The only point that came close IMHO was the possible
overhead factor. That was a good point, but in my mind, probably
not enough reason to avoid it.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 21:12               ` Warren W. Gay VE3WWG
@ 2003-02-18 23:20                 ` Randy Brukardt
  2003-02-19 18:28                   ` Warren W. Gay VE3WWG
  2003-02-20  7:50                   ` Dale Stanbrough
  2003-02-19 12:49                 ` Marin David Condic
  1 sibling, 2 replies; 57+ messages in thread
From: Randy Brukardt @ 2003-02-18 23:20 UTC (permalink / raw)



Warren W. Gay VE3WWG wrote in message <3E52A1BF.1020809@cogeco.ca>...
>Randy Brukardt wrote:

>> The big problem with the variant interface is that everything has to
be
>> defined in one place.
>
>Why is that a problem? XEvent does this too. So?


Keep reading...

>> That's usually not practical. The notification
>> data includes various data types specific to each of the types of
>> controls.
>
>OK, I can see that you might have some package interdependency
>issues, depending on the data _types_ being used. I do believe
>however, that careful planning can avoid these problems.


Not practical, unless you plan to eliminate most type checking (that is,
most of the advantages of Ada).

>> If we had to put all of that in the spec. of the Claw root
>> package, we'd more than double its size (and its already 5000 lines).
>
>So? What problem? Longer compile times? Is that what we're worried
>about? It may be a consideration, but not necessarily a
>deciding factor.


Readability, of course. And excess coupling. (It's the coupling that
causes other things to be dragged in).

>> If we had used a variant solution, there
>> would be no possibility of that, as every possible control would have
to
>> be reflected in that variant.
>
>This is patently false.
>
>I don't believe that just because a variant record is used that this
>eliminates the possibility of a cleanup.  The reason is this: you only
>carry _EVENT_ data in this variant record -- not widget internal data.
>This event data can be used to communicate with many widget callbacks.
>
>Perhaps you misunderstand what I am suggesting here -- I am not
>suggesting widgets in a variant record. Oh, no! Only _event_ data.


I'm only talking about "event" data. Let's look at some of the
notification event data.

For a tree view control, the standard notification includes the
following components:
     Old_Item_Handle, New_Item_Handle, Old_Item_State, New_Item_State,
Old_Item_DWord,
     New_Item_DWord, Action, and Point.
The notification gets sent when the selection changes, when an item is
expanded (or contracted), when an item is deleted, when an item is
dragged, and more.

In order to make this into a possible variant, we'd have to pull all of
the handle and state declarations into the root Claw package. (States
are usually private types in Claw along with a set of constants and
operations -- no direct bit operations). That would be a lot of excess
coupling. Moreover, we'd need to do that for every type of control that
has its own distinct state; there are around ten of them currently.

We'd also have to expose (unsafely) much more of the low level guts of
Claw. For instance, we use the 'user-defined dword' to hold an access to
the Ada version of the item. In our interface, we simply declare this to
be:
        Old_Item : Claw.Tree_View.Any_Item_Access_Type;
But, if we moved that to the root Claw as you suggest, we wouldn't be
able to use the access type (not without moving the bulk of the
Tree_View package into the root Claw -- surely you can't be suggesting
that!). So, we'd have to open this up to some sort of user conversions,
both more error-prone and more likely to be abused.

Of course lumping all of that into the Claw root package makes all of
those things harder to find, as it is no longer declared with its
related code. Root packages should be as small as possible, not full of
unrelated garbage.

Anyway, my position is very simple: minimizing coupling is good. And
having to put stuff in a variant in a root package that doesn't
logically belong there is unnecessary (bad coupling).

>> Since we used a tagged type, we don't have
>> to drag in Tree Views unless the user actually withs Claw.Tree_View.
>> (That was happening for another reason, and the internal
restructuring
>> eliminated that.) That cut the average size of Claw programs by 500K.
>
>Look at the way XEvents is defined. It does not define a member for
each
>widget. It defines a view for each _event_ type. The members correspond
to
>needs of the _event_ _communication_.  Nothing you have said has
invalidated
>this approach.

I think you have a completely different idea of what an event is than I
do. You're thinking at the level of X11, which is a low-level graphics
environment. It has very simple events like "mouse moved" and "key
pressed".

While those are clearly events, there are also events specific to a
particular control (or widget, if you prefer), like "Button pressed".
And most importantly for this discussion, there are events that are
meaningful for many controls, like "item selected". The data that gets
sent with a "item selected" event is specific to the control that sent
it, but the event is common to all controls.

>> But that's a pretty limited GUI (and calling X11 a GUI is a stretch).
>
>Um, MOTIF, which is used UNIX-wide, is entirely built upon X11.
>Not to mention that Gtk also builds upon X11 in the environments
>that require it. The X intrinsics build upon X11 to provide the
>widget foundation and callbacks, that other widget sets in X use
>(like MOTIF/LessTif).  All of these layers use callbacks and
>event data. If this aint a serious GUI, then tell me why
>the LessTif team has taken several years to duplicate MOTIF 2? ;-)
>It is, and continues to be.

MOTIF is a GUI. X11 is not; it's more of a toolkit for building GUIs.
Windows is built on top of GDI, but I don't think anyone would call GDI
a GUI.

In any case, my point is that there are a lot more kinds of events in
the full-blown GUI than there are in X11 itself. (I should point out
that its been years since I've had any reason to look at X11, so I'm
working from old memories of X.)

>But my point has always been in this
>thread is that there has been no good reason given that event data
>cannot be provided in a callback parameter as a variant record.


For simple events, I prefer to simply provide the data as parameters to
the action routine (the event handler that you override in an OOP GUI
like Claw). And, if the events are sufficiently different, I'll provide
different routines for them. For example, I certainly see no reason to
share the handler for a keypress and a mouse click. That usually
eliminates the need for complex data structures of any sort.

            Randy.






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18  1:37         ` Jeffrey Carter
  2003-02-18  3:39           ` Warren W. Gay VE3WWG
@ 2003-02-18 23:36           ` Randy Brukardt
  1 sibling, 0 replies; 57+ messages in thread
From: Randy Brukardt @ 2003-02-18 23:36 UTC (permalink / raw)


Jeffrey Carter wrote in message <3E518EA0.1080702@acm.org>...
>> It might be easier to start with a tagged object, where methods can
>> be inherited and overriden instead. That way all events can just
>> do nothing, while you override the events you are interested in.
>> But this takes us back to a model similar to callbacks anyways, but
>> instead of registering a callback, you register a tagged record
>> to receive callbacks.
>
>This is the approach taken by CLAW. A widget is represented by a tagged
>type, with primitive operations that are called automatically when
>certain events occur. There are default versions of these operations.
To
>create a widget with specific behavior, you have to extend the type and
>override the appropriate operations. This can be useful when you want
to
>have data associated with a widget, as you can define the data as part
>of the extension, give the widget values when you create it, and check
>the values in the operations. But when all you want is to define the
>application's behavior when the user clicks a button, it seems like
>overkill. Consider a window with lots of buttons, different behavior
>when each button is clicked, and little or nothing else in the way of
>user input. This calls for many extensions and many overridings of the
>appropriate operation. It differs from callbacks in not requiring
>operations to be registered with the windowing system, but similar in
>that the windowing system controls your application.


That's not quite right. In Claw (as in MFC, but not quite as in
Windows), notifications are passed first to the control item, then to
the parent window of the control. In most cases, you handle
notifications in the parent window in order to avoid the need to
override so many items. The result isn't quite so pretty, but its a lot
easier to maintain (because there are far fewer packages and types).
This is also convinient for handling the data, which is usually shared
between multiple controls:

A typically handler would look like:

     procedure When_Child_Notify (Window  : in out My_Dialog;
                                 Code    : in
Claw.Notification_Code_Type;
                                 Data    : in
Claw.Notification_Data_Type'Class
                                 Control : in out
Claw.Root_Control_Type'Class;
                                 Unknown_Command : in out Boolean;
                                 Result_Value : in out
Claw.Win32.LResult) is
        use type Claw.Notification_Code_Type;
        use type Claw.Root_Control_Type;
    begin
        if Code = Claw.Buttons.Button_Clicked then
            if Control = Window.Button_1 then
                -- Do whatever.
                Unknown_Command := False;
            elsif Control = Window.Button_2 then
                -- Do whatever.
                Unknown_Command := False;
            else
                 Unknown_Command := True;
            end if;
        else
            Unknown_Command := True;
        end if;
        if Unknown_Command then -- Call the parent routine for default
processing:
               Claw.Dialog.Modal.When_Child_Notify (
                    Claw.Dialog.Modal.Modal_Dialog_Type(Window),
                    Code, Data, Control, Unknown_Command, Result_Value);
        end if;
   end When_Child_Notify;

(Note that calling the parent routine is harder to write and more likely
to break in Ada 95 than it really ought to be, because you have to
identify the parent type in it.  If the parent type changes, this call
may be wrong. I hope that the upcoming Amendment will address this
problem.)

           Randy.





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 21:12               ` Warren W. Gay VE3WWG
  2003-02-18 23:20                 ` Randy Brukardt
@ 2003-02-19 12:49                 ` Marin David Condic
  2003-02-19 18:35                   ` [OT] Best way to isolate a GUI? (The final concensous?) Warren W. Gay VE3WWG
  2003-02-20  8:26                   ` [OT] Best way to isolate a GUI? tmoran
  1 sibling, 2 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-19 12:49 UTC (permalink / raw)


Why would you want to use a variant record when a tagged type solves the
problem so much more elegantly? I've always found variant records to be a
pain in the posterior - in particular as noted by Randy that you have to
define everything in one place. If you wanted to pass back to an app various
events (or widget data, for that matter) it would seem that a base class of
some sort of "event" or "message" would be the place to start. You then
build up from that class the specific events or messages you need in
separate packages. If something gets added on top that message catalog,
you're not impacting anything else and the extension doesn't force
recompilation of the whole world.

Short of possibly efficiency concerns or representation issues, I just don't
see much excuse for variant records when we've got tagged types.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E52A1BF.1020809@cogeco.ca...
>
> You brought some interesting points to the discussion, but none
> that would convince me that variant records are unsuitable for
> the job. The only point that came close IMHO was the possible
> overhead factor. That was a good point, but in my mind, probably
> not enough reason to avoid it.
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 18:01           ` Warren W. Gay VE3WWG
@ 2003-02-19 13:06             ` Marin David Condic
  0 siblings, 0 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-19 13:06 UTC (permalink / raw)


Well, for the sender, there needs to be only one queue. For the receiver,
you're ultimately going to end up with case statements - either one big
giant one explicitly created or a bunch of smaller ones inside various
handling tasks or ones that are built for you via dispatching. I have not
given the idea hundreds of hours of thought yet, but I'm sure a workable
solution does exist. I've just never liked callbacks and thought that
receiving messages in some manner is a much better answer.

I've worked on systems (mostly LockMart stuff, but I know other companies
did it) where there is an underlying messaging system where applications
"register" for the messages they want to receive & create "mailboxes" to
receive them. You basically end up with one process per computer that acts
as the "mailman". It makes for a reasonably simple & elegant design of an
app where a given task need only hear about the things it wants to do
something about. It solves a lot of other problems along the way like socket
overhead and needing to know about what else is out there attempting to
communicate. It has its problems too, but in general its a good way to build
loosely coupled distributed applications. I could imagine something similar
working in a client/server mode to build an independent GUI without
callbacks or excessively big case statements. You create a task for each
window and it registers for events relating to that window. Its still got to
have a case statement - or some kind of dispatching - but its localized.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E527506.6070209@cogeco.ca...
>
> But this still suffers from one problem: Each queue in your task
> would then have a monster case statement to split out the work
> according to the widget that is receiving the event. Compare this
> to the registered callback where only the interested widget for
> the event gets the callback. No big case statement required for
> event, or widget.
>
> Don't get me wrong.. I like the idea of queues and tasks. But this seems
> a clumsy thing beside a callback.
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 23:20                 ` Randy Brukardt
@ 2003-02-19 18:28                   ` Warren W. Gay VE3WWG
  2003-02-20 19:39                     ` Randy Brukardt
  2003-02-20  7:50                   ` Dale Stanbrough
  1 sibling, 1 reply; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-19 18:28 UTC (permalink / raw)


Randy Brukardt wrote:
> Warren W. Gay VE3WWG wrote in message <3E52A1BF.1020809@cogeco.ca>...
>>Randy Brukardt wrote:
>>>That's usually not practical. The notification
>>>data includes various data types specific to each of the types of
>>>controls.
>>
>>OK, I can see that you might have some package interdependency
>>issues, depending on the data _types_ being used. I do believe
>>however, that careful planning can avoid these problems.
> 
> Not practical, unless you plan to eliminate most type checking (that is,
> most of the advantages of Ada).

I disagree. You can combine a base class (tagged record) with
variant records. This gives you the best of both worlds.

>>>If we had to put all of that in the spec. of the Claw root
>>>package, we'd more than double its size (and its already 5000 lines).
>>
>>So? What problem? Longer compile times? Is that what we're worried
>>about? It may be a consideration, but not necessarily a
>>deciding factor.
> 
> Readability, of course. And excess coupling. (It's the coupling that
> causes other things to be dragged in).
> 
>>>If we had used a variant solution, there
>>>would be no possibility of that, as every possible control would have to
>>>be reflected in that variant.
>>
>>This is patently false.
>>
>>I don't believe that just because a variant record is used that this
>>eliminates the possibility of a cleanup.  The reason is this: you only
>>carry _EVENT_ data in this variant record -- not widget internal data.
>>This event data can be used to communicate with many widget callbacks.
>>
>>Perhaps you misunderstand what I am suggesting here -- I am not
>>suggesting widgets in a variant record. Oh, no! Only _event_ data.
> 
> I'm only talking about "event" data. Let's look at some of the
> notification event data.
> 
> For a tree view control, the standard notification includes the
> following components:
>      Old_Item_Handle, New_Item_Handle, Old_Item_State, New_Item_State,
> Old_Item_DWord,
>      New_Item_DWord, Action, and Point.
> The notification gets sent when the selection changes, when an item is
> expanded (or contracted), when an item is deleted, when an item is
> dragged, and more.
> 
> In order to make this into a possible variant, we'd have to pull all of
> the handle and state declarations into the root Claw package. 

OK, but why not use a tagged "base type" for the event data. Then for
callbacks that need "extended event data", you can test and convert
the type to the type it really is. But, within the tagged type, you
can still make use of variant records for those events that vary
according to purpose/event.  The variants can exist at both the
base level and at the "extended level".  I still do not see anything
here that precludes the use of variant records.

...
>>>Since we used a tagged type, we don't have
>>>to drag in Tree Views unless the user actually withs Claw.Tree_View.
>>>(That was happening for another reason, and the internal restructuring
>>>eliminated that.) That cut the average size of Claw programs by 500K.
>>
>>Look at the way XEvents is defined. It does not define a member for each
>>widget. It defines a view for each _event_ type. The members correspond to
>>needs of the _event_ _communication_.  Nothing you have said has invalidated
>>this approach.
> 
> I think you have a completely different idea of what an event is than I
> do. You're thinking at the level of X11, which is a low-level graphics
> environment. It has very simple events like "mouse moved" and "key
> pressed".

This is true of course. I grabbed the MOTIF book off of the shelf this
morning (before breakfast even ;-) and reviewed the callbacks that it
and the Xt (intrinsics) define in the callback interface. It is true
that they use a different "model" interface: they provide two XtPointer
values in addition to the widget. The callback code then is expected
to cast this pointer to the correct structure type, which, IMHO is
ghastly. So you do have a point -- I'll concede at this level. :(

However, I still think that a combination of a base tagged type with
the use of variant records would provide the best of all solutions
for the callback interface.

I guess your point is probably why use variant records at all, when
tagged records will do?  I need to think about that more, but the
one objection I have is that it is easier to case on the record's
discriminant then to do "if event in Some_Widget'Class then" tests
in code that needs to perform those tests.

> While those are clearly events, there are also events specific to a
> particular control (or widget, if you prefer), like "Button pressed".
> And most importantly for this discussion, there are events that are
> meaningful for many controls, like "item selected". The data that gets
> sent with a "item selected" event is specific to the control that sent
> it, but the event is common to all controls.

Agreed.  Which I suppose is why you like the tagged record approach.
I am not entirely disagreeing at this point, but I still seem
room for variant record "participation" ;-)

Certainly as you've pointed out, the tagged record approach allows
you to bury its specifics in other package specs.  I have to admit
that I like that.

>>>But that's a pretty limited GUI (and calling X11 a GUI is a stretch).
>>
>>Um, MOTIF, which is used UNIX-wide, is entirely built upon X11.
>>Not to mention that Gtk also builds upon X11 in the environments
>>that require it. The X intrinsics build upon X11 to provide the
>>widget foundation and callbacks, that other widget sets in X use
>>(like MOTIF/LessTif).  All of these layers use callbacks and
>>event data. If this aint a serious GUI, then tell me why
>>the LessTif team has taken several years to duplicate MOTIF 2? ;-)
>>It is, and continues to be.
> 
> 
> MOTIF is a GUI. X11 is not; it's more of a toolkit for building GUIs.
> Windows is built on top of GDI, but I don't think anyone would call GDI
> a GUI.

Well, OK. But we're splitting straws here I think -- X11 is graphical,
it is an interface, and it is used by a user (hence GUI). There are
some (albiet limited) applications that only make use of the X11
library. But I'll concede the point, if it helps.

> In any case, my point is that there are a lot more kinds of events in
> the full-blown GUI than there are in X11 itself. (I should point out
> that its been years since I've had any reason to look at X11, so I'm
> working from old memories of X.)

I won't disagree with that. In fact, to some degree, I think you've
managed to successfully present the tagged record approach as a good
callback approach for two reasons that I would consider key:

   1. Reduces one central "definition" of the event to a base type (or set)
   2. Allows easy extendability of the event object as new widgets
      are developed.

>>But my point has always been in this
>>thread is that there has been no good reason given that event data
>>cannot be provided in a callback parameter as a variant record.
> 
> For simple events, I prefer to simply provide the data as parameters to
> the action routine (the event handler that you override in an OOP GUI
> like Claw). And, if the events are sufficiently different, I'll provide
> different routines for them. For example, I certainly see no reason to
> share the handler for a keypress and a mouse click. That usually
> eliminates the need for complex data structures of any sort.
> 
>             Randy.

 From a "client perspective", I would agree with this. But with my
library writer's hat on I don't because that means I have to define
different collections of callbacks. Whereas if you define one type
of callback interface, say something like:

    procedure Callback(W : Widget_Type; Event : Event_Type'Class; User_Data_Ref : ...);

then you can centralize code to call a callback list, add to and delete
from the callback list. All widgets can then be built to use the same
resources.

Ok. You have sold me on tagged types for the event info. However, I
still some application for variants within those tagged types ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-19 12:49                 ` Marin David Condic
@ 2003-02-19 18:35                   ` Warren W. Gay VE3WWG
  2003-02-20 12:40                     ` Marin David Condic
  2003-02-20  8:26                   ` [OT] Best way to isolate a GUI? tmoran
  1 sibling, 1 reply; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-19 18:35 UTC (permalink / raw)


Marin David Condic wrote:
> Why would you want to use a variant record when a tagged type solves the
> problem so much more elegantly? I've always found variant records to be a
> pain in the posterior - in particular as noted by Randy that you have to
> define everything in one place. If you wanted to pass back to an app various
> events (or widget data, for that matter) it would seem that a base class of
> some sort of "event" or "message" would be the place to start. You then
> build up from that class the specific events or messages you need in
> separate packages. If something gets added on top that message catalog,
> you're not impacting anything else and the extension doesn't force
> recompilation of the whole world.
> 
> Short of possibly efficiency concerns or representation issues, I just don't
> see much excuse for variant records when we've got tagged types.
> 
> MDC
> --

For the most part Marin, I have conceded the point to Randy. Tagged
records provide one very important advantage, that I consider to
be important: the fact that you can define a simple base type, and
then extend it from separate other package specs as needed. That
feature is very much worth having, IMO.

Tagged records need not be the final answer to all things event wise
however. Doing a case statement on a discriminant of a variant record
is easier than doing a number of "if object in Some'Class then"
tests. Especially if there is a common set of elements and some
variations for the event in question.

So my concession is this:

   1) Use tagged types for event data (with a abstract or bare "base" type).
   2) Extend the event base type in the package specs as required
   3) Callback is defined as receiving some Base'Class argument.
   4) Within the final tagged type, perhaps use variant records to
      distinguish variations of that event.

Basically I guess where I am coming from is that I don't see a tagged
type for "every variation". That is perhaps a point where we'll
all disagree ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-18 23:20                 ` Randy Brukardt
  2003-02-19 18:28                   ` Warren W. Gay VE3WWG
@ 2003-02-20  7:50                   ` Dale Stanbrough
  1 sibling, 0 replies; 57+ messages in thread
From: Dale Stanbrough @ 2003-02-20  7:50 UTC (permalink / raw)


In article <v55fr8fmg58q67@corp.supernews.com>,
 "Randy Brukardt" <randy@rrsoftware.com> wrote:

> MOTIF is a GUI. X11 is not; it's more of a toolkit for building GUIs.
> Windows is built on top of GDI, but I don't think anyone would call GDI
> a GUI.

Actually X11 is a communications protocol, an API and an
interpreter.
Xt is a toolkit (X Toolkit :-), and Motif a collection of
widgets built with that toolkit that follow a consistent style.

Dale



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-19 12:49                 ` Marin David Condic
  2003-02-19 18:35                   ` [OT] Best way to isolate a GUI? (The final concensous?) Warren W. Gay VE3WWG
@ 2003-02-20  8:26                   ` tmoran
  2003-02-20 12:51                     ` Marin David Condic
  1 sibling, 1 reply; 57+ messages in thread
From: tmoran @ 2003-02-20  8:26 UTC (permalink / raw)


>Short of possibly efficiency concerns or representation issues, I just don't
>see much excuse for variant records when we've got tagged types.
  Whoa there!  If you have default discriminants, you can have
Transport : Vehicle(Kind=>Car, Horsepower=>100);
and later
  Transport := (Kind=>Truck, Axle_Count=>3, Capacity => Tons'(0.5));
and the compiler will even warn you if you forget and try:
  Transport := (Kind=>Truck, Capacity => Tons'(0.5));
That's a lot simpler than futzing with
  Transport : Vehicle_Ptr := new Car'(Horsepower=>100);
etc



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-19 18:35                   ` [OT] Best way to isolate a GUI? (The final concensous?) Warren W. Gay VE3WWG
@ 2003-02-20 12:40                     ` Marin David Condic
  2003-02-20 13:13                       ` Dmitry A. Kazakov
  2003-02-20 22:01                       ` Warren W. Gay VE3WWG
  0 siblings, 2 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-20 12:40 UTC (permalink / raw)


I'd put the case statement part in the "Nice to have" category rather than
view it as the loss of some essential capability. Most of what you get there
is likely to be dealt with by dispatching & the rest is more of an
inconvenience than anything else.

I'd agree that you don't want to totally rule out variant records.It is a
foolish design rule to say "Thou shalt not use feature X - ever." I'd simply
base the thing on tagged records and as the design evolved if circumstances
made it look like a variant might be a good answer, go ahead and create one.
My strategy would be tagged records, but I might use a tactic of a variant
occasionally.

As for callbacks - I'd rather not see that at all. One or more message
queues would seem more elegant to me. Maybe that's just me, but callbacks
seem like some version of a computed goto - I've got to give you intimate
knowledge of the inside of my code (plus, structure my code according to
your whims) when I'd rather just have you send me data and let me figure out
what to do with it.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E53CE60.1030008@cogeco.ca...
>
> Tagged records need not be the final answer to all things event wise
> however. Doing a case statement on a discriminant of a variant record
> is easier than doing a number of "if object in Some'Class then"
> tests. Especially if there is a common set of elements and some
> variations for the event in question.
>
> So my concession is this:
>
>    1) Use tagged types for event data (with a abstract or bare "base"
type).
>    2) Extend the event base type in the package specs as required
>    3) Callback is defined as receiving some Base'Class argument.
>    4) Within the final tagged type, perhaps use variant records to
>       distinguish variations of that event.
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-20  8:26                   ` [OT] Best way to isolate a GUI? tmoran
@ 2003-02-20 12:51                     ` Marin David Condic
  2003-02-20 18:47                       ` tmoran
  0 siblings, 1 reply; 57+ messages in thread
From: Marin David Condic @ 2003-02-20 12:51 UTC (permalink / raw)


Oh, there may be cases here and there. And its always easy to construct an
artificial scenario where variant records look better. Just that in
practice, the places where I've used variant records have usually turned out
to be more elegantly and less painfully dealt with by tagged records. I've
got Ada83 code where its been used - usually for some sort of message and
occasionally for some sort of parser thing - and in all the cases where I've
seen it & used it, I'd rather have substituted a base class with dispatching
operations. Its a personal judgement call and based on field usage rather
than a language rule or academic concern.

I'd never tell anyone they *couldn't* use variant records and I wouldn't
suggest removing them from the language. I've just found them to be a big
pain in comparison to tagged records in most of the uses I've come across.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

<tmoran@acm.org> wrote in message news:Ri05a.173335$tq4.4827@sccrnsc01...
> >Short of possibly efficiency concerns or representation issues, I just
don't
> >see much excuse for variant records when we've got tagged types.
>   Whoa there!  If you have default discriminants, you can have
> Transport : Vehicle(Kind=>Car, Horsepower=>100);
> and later
>   Transport := (Kind=>Truck, Axle_Count=>3, Capacity => Tons'(0.5));
> and the compiler will even warn you if you forget and try:
>   Transport := (Kind=>Truck, Capacity => Tons'(0.5));
> That's a lot simpler than futzing with
>   Transport : Vehicle_Ptr := new Car'(Horsepower=>100);
> etc





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-20 12:40                     ` Marin David Condic
@ 2003-02-20 13:13                       ` Dmitry A. Kazakov
  2003-02-20 22:01                       ` Warren W. Gay VE3WWG
  1 sibling, 0 replies; 57+ messages in thread
From: Dmitry A. Kazakov @ 2003-02-20 13:13 UTC (permalink / raw)


On Thu, 20 Feb 2003 07:40:02 -0500, "Marin David Condic"
<mcondic.auntie.spam@acm.org> wrote:

>I'd put the case statement part in the "Nice to have" category rather than
>view it as the loss of some essential capability. Most of what you get there
>is likely to be dealt with by dispatching & the rest is more of an
>inconvenience than anything else.
>
>I'd agree that you don't want to totally rule out variant records.It is a
>foolish design rule to say "Thou shalt not use feature X - ever." I'd simply
>base the thing on tagged records and as the design evolved if circumstances
>made it look like a variant might be a good answer, go ahead and create one.
>My strategy would be tagged records, but I might use a tactic of a variant
>occasionally.
>
>As for callbacks - I'd rather not see that at all. One or more message
>queues would seem more elegant to me. Maybe that's just me, but callbacks
>seem like some version of a computed goto - I've got to give you intimate
>knowledge of the inside of my code (plus, structure my code according to
>your whims) when I'd rather just have you send me data and let me figure out
>what to do with it.

Callbacks use the caller's context, messages do not. This could be
crucial in some cases. A painful example of this difference is task
entries which are unable to return indefinite objects. Anyway, Ada
offers a great variety of design options to consider.

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-20 12:51                     ` Marin David Condic
@ 2003-02-20 18:47                       ` tmoran
  0 siblings, 0 replies; 57+ messages in thread
From: tmoran @ 2003-02-20 18:47 UTC (permalink / raw)


>Oh, there may be cases here and there. And its always easy to construct an
>artificial scenario where variant records look better. Just that in
>practice, the places where I've used variant records have usually turned out
>to be more elegantly and less painfully dealt with by tagged records.
  Not two weeks ago I had to write code to watch data going by and
catch certain patterns, essentially a simple kind of parser.  Each pattern
required somewhat different information to be accumulated, so
  type pattern_kinds is (none, a,b,c);
  type states(kind : pattern_kinds := none) is record
    case kind is
      when none => null;
      when a    => -- data accumulators for pattern type a
      when b    => -- data accumulators for pattern type b
      etc
  current_state : states(kind=>none);
did the job nicely.  To change state takes a simple assignment, not any
freeing or allocating of classwide pointers.  The assignment has to be a
whole record assignment, so there's no chance of forgetting to initialize
some part of the data for pattern x.  If a new pattern is added it needs
no modifications to the code for existing patterns.  If new data fields
are added for pattern x, the compiler will flag any assignment that
fails to include the new field in the aggregate.  An attempt to use
a field of pattern "a" while "kind = b", will be caught.
  How would you do this with tagged records?



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-19 18:28                   ` Warren W. Gay VE3WWG
@ 2003-02-20 19:39                     ` Randy Brukardt
  2003-02-20 21:34                       ` Warren W. Gay VE3WWG
  0 siblings, 1 reply; 57+ messages in thread
From: Randy Brukardt @ 2003-02-20 19:39 UTC (permalink / raw)


Warren W. Gay VE3WWG wrote in message <3E53CCDF.1090509@cogeco.ca>...
>Randy Brukardt wrote:
>> In any case, my point is that there are a lot more kinds of events in
>> the full-blown GUI than there are in X11 itself. (I should point out
>> that its been years since I've had any reason to look at X11, so I'm
>> working from old memories of X.)
>
>I won't disagree with that. In fact, to some degree, I think you've
>managed to successfully present the tagged record approach as a good
>callback approach for two reasons that I would consider key:
>
>   1. Reduces one central "definition" of the event to a base type (or
set)
>   2. Allows easy extendability of the event object as new widgets
>      are developed.

Yes, exactly. These are precisely why we used the tagged approach.

>>>But my point has always been in this
>>>thread is that there has been no good reason given that event data
>>>cannot be provided in a callback parameter as a variant record.
>>
>> For simple events, I prefer to simply provide the data as parameters
to
>> the action routine (the event handler that you override in an OOP GUI
>> like Claw). And, if the events are sufficiently different, I'll
provide
>> different routines for them. For example, I certainly see no reason
to
>> share the handler for a keypress and a mouse click. That usually
>> eliminates the need for complex data structures of any sort.
>
> From a "client perspective", I would agree with this. But with my
>library writer's hat on I don't because that means I have to define
>different collections of callbacks. Whereas if you define one type
>of callback interface, say something like:
>
>    procedure Callback(W : Widget_Type; Event : Event_Type'Class;
User_Data_Ref : ...);
>
>then you can centralize code to call a callback list, add to and delete
>from the callback list. All widgets can then be built to use the same
>resources.


Remember the ease of writing is WAY down on the list of good things for
Ada, and we certainly followed this approach with Claw. Our goals for
the interface were (not necessarily in this order):
   -- Avoid unnecessary overhead in the implementation of the interface;
   -- Insure that the interface prevents common errors, preferably at
compile-time;
   -- Make the interface easy to use for the client.

Our effort in writing the interface was never an issue. Of course, we
expect many people to use it, and thus the effort spent in meeting the
goals will pay off over time.

>Ok. You have sold me on tagged types for the event info. However, I
>still some application for variants within those tagged types ;-)


Like Marin, I'll never say "never use" something, because that's silly.
If a variant makes sense in a particular extension, by all means use it.
But the base item should be a tagged root type of some sort, not a
massive variant.

I think we finally agree.

              Randy.





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI?
  2003-02-20 19:39                     ` Randy Brukardt
@ 2003-02-20 21:34                       ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-20 21:34 UTC (permalink / raw)


Randy Brukardt wrote:
> Warren W. Gay VE3WWG wrote in message <3E53CCDF.1090509@cogeco.ca>...
> 
>>Randy Brukardt wrote:
>>
>>>In any case, my point is that there are a lot more kinds of events in
>>>the full-blown GUI than there are in X11 itself. (I should point out
>>>that its been years since I've had any reason to look at X11, so I'm
>>>working from old memories of X.)
>>
>>I won't disagree with that. In fact, to some degree, I think you've
>>managed to successfully present the tagged record approach as a good
>>callback approach for two reasons that I would consider key:
>>
>>  1. Reduces one central "definition" of the event to a base type (or set)
> 
>>  2. Allows easy extendability of the event object as new widgets
>>     are developed.
> 
> Yes, exactly. These are precisely why we used the tagged approach.

It took a little convincing, but I am sold on this now ;-)

>>>>But my point has always been in this
>>>>thread is that there has been no good reason given that event data
>>>>cannot be provided in a callback parameter as a variant record.
>>>
>>>For simple events, I prefer to simply provide the data as parameters to
>>>the action routine (the event handler that you override in an OOP GUI
>>>like Claw). And, if the events are sufficiently different, I'll
>>>provide different routines for them. For example, I certainly see no reason
>>>to share the handler for a keypress and a mouse click. That usually
>>>eliminates the need for complex data structures of any sort.
>>
>>From a "client perspective", I would agree with this. But with my
>>library writer's hat on I don't because that means I have to define
>>different collections of callbacks. Whereas if you define one type
>>of callback interface, say something like:
>>
>>   procedure Callback(W : Widget_Type; Event : Event_Type'Class;
> 
> User_Data_Ref : ...);
> 
>>then you can centralize code to call a callback list, add to and delete
>>from the callback list. All widgets can then be built to use the same
>>resources.
> 
> Remember the ease of writing is WAY down on the list of good things for
> Ada, 

Yes, I agree with this.

> and we certainly followed this approach with Claw. Our goals for
> the interface were (not necessarily in this order):
>    -- Avoid unnecessary overhead in the implementation of the interface;
>    -- Insure that the interface prevents common errors, preferably at compile-time;
>    -- Make the interface easy to use for the client.

I tend to put "overhead" in the lowest category as long as the overhead
is "reasonable"; at least for projects like a UI. I would personally
rate your last two points higher for example, if I were to rate them
(all of them goals that I would agree with).

> Our effort in writing the interface was never an issue. Of course, we
> expect many people to use it, and thus the effort spent in meeting the
> goals will pay off over time.

That's what I prefer to see, for sure : long term goals with long
term payoffs.

>>Ok. You have sold me on tagged types for the event info. However, I
>>still some application for variants within those tagged types ;-)
> 
> Like Marin, I'll never say "never use" something, because that's silly.
> If a variant makes sense in a particular extension, by all means use it.
> But the base item should be a tagged root type of some sort, not a
> massive variant.
> 
> I think we finally agree.
> 
>               Randy.

Yes. In fact, more than this.. 8-O

I liked your idea of taking what I call the "application
context" object and extending it to provide the access to the user data.
By doing this, I was able to eliminate a system.address and a ghastly
generic procedure to convert address to User_Data_Ptr.

The only downside
to this, is that the user must continually "convert" the ACTX_Type to a
User_Data type, to reference members (the ACTX_Type is a controlled limited
type).

     type User_Data is new ACTX_Type with
        record
           Whatever : Boolean;  -- User data member(s)
        end;

     procedure Callback(ACTX : ACTX_Type'Class; ...) is
     begin
        User_Data(ACTX).Whatever := True;
        ...

I suppose if you have many refs to the user data type, you can call
a procedure with the type converted as in:

     Yet_Another_Proc(User_Data(ACTX),...)

where

     procedure Yet_Another_Proc(UD : in out User_Data; ...) is
     begin
        UD.Whatever := ...;

as either an internal or external procedure.

Thanks for the effort of convincing  ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-20 12:40                     ` Marin David Condic
  2003-02-20 13:13                       ` Dmitry A. Kazakov
@ 2003-02-20 22:01                       ` Warren W. Gay VE3WWG
  2003-02-21  1:25                         ` tmoran
  2003-02-21  2:08                         ` Marin David Condic
  1 sibling, 2 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-20 22:01 UTC (permalink / raw)


Marin David Condic wrote:
> I'd put the case statement part in the "Nice to have" category rather than
> view it as the loss of some essential capability. Most of what you get there
> is likely to be dealt with by dispatching & the rest is more of an
> inconvenience than anything else.
> 
> I'd agree that you don't want to totally rule out variant records.It is a
> foolish design rule to say "Thou shalt not use feature X - ever." I'd simply
> base the thing on tagged records and as the design evolved if circumstances
> made it look like a variant might be a good answer, go ahead and create one.
> My strategy would be tagged records, but I might use a tactic of a variant
> occasionally.
> 
> As for callbacks - I'd rather not see that at all. One or more message
> queues would seem more elegant to me. Maybe that's just me, but callbacks
> seem like some version of a computed goto - I've got to give you intimate
> knowledge of the inside of my code (plus, structure my code according to
> your whims) when I'd rather just have you send me data and let me figure out
> what to do with it.
> 
> MDC
...

I don't think you can easily avoid callbacks. The problem with GUIs is
that they tend to be dynamic. A popup is created (which has events),
and then is gone, for example. A task with queue entries tends to be
static in form. So if you end up with a task & queue model, you must
somehow permit dynamic wiring in of events somehow, and it tends
to be inconvenient in a static "form".

I was thinking of the requirements of the OP query, about
the isolation factor. Perhaps this has already been stated, but the
task & entry idea is not a bad one if you use the callbacks do
the rendezvous with the task. The callbacks handle the dynamic
linkage between the GUI and the task (callbacks = glue or wiring).
This is perhaps what you've been saying all along..

Then you simply specialize the queues accord
to events and widgets as required.  If properly done, you should be
able to link with a X11/MOTIF, Windows, GtkAda or whatever library
and maintain the same core.  At least that is the theory.

The one place where you might get foiled is the way that user data
is handled by each GUI.  To do this, I think you might need to use
a preprocessor like gnatprep.  Is this true?  Hmmm..

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-20 22:01                       ` Warren W. Gay VE3WWG
@ 2003-02-21  1:25                         ` tmoran
  2003-02-21  2:08                         ` Marin David Condic
  1 sibling, 0 replies; 57+ messages in thread
From: tmoran @ 2003-02-21  1:25 UTC (permalink / raw)


> I don't think you can easily avoid callbacks.
  I think of callbacks (whether done with function pointers or overriding
a tagged type's primitive ops) as interrupts.  Does anyone use the
Real-Time Systems Annex Interrupt handling stuff for callbacks?
  If you think of callbacks as equivalent to a series of guarded "accept"s
in a giant "select" in a loop, where the guard handles callback
registration, then that's clearly a highly restricted special case of
tasking.  Both that and the interrupt model assume that a callback has
complete control for a short time until its event is, in some sense,
completed.  Awfully restrictive style, but perhaps appropriate for the
millions of programmers unfamiliar with the ins and outs of multi-tasking
programming.



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-20 22:01                       ` Warren W. Gay VE3WWG
  2003-02-21  1:25                         ` tmoran
@ 2003-02-21  2:08                         ` Marin David Condic
  2003-02-21 17:27                           ` Jeffrey Carter
  2003-02-21 18:02                           ` Warren W. Gay VE3WWG
  1 sibling, 2 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-21  2:08 UTC (permalink / raw)



Well, if you use an existing GUI such as Windows or Motif, you are *going*
to have callbacks. I'd prefer to isolate them in some kind of wrapper layer
and have the "real" app receive messages of some sort. If you were building
a GUI from bottom dead center, you could build that sort of thing right in.
I'm just saying I think that callbacks are an ugly kludge that I'd prefer
were done a different way. You might be able to get there with existing GUIs
& glue or wrappers or skins or whatever you like to call it. Just expressing
a desire to see an interface to a GUI that doesn't have to know anything
about the code *I* write. :-)

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E55501D.9050006@cogeco.ca...
>
> I was thinking of the requirements of the OP query, about
> the isolation factor. Perhaps this has already been stated, but the
> task & entry idea is not a bad one if you use the callbacks do
> the rendezvous with the task. The callbacks handle the dynamic
> linkage between the GUI and the task (callbacks = glue or wiring).
> This is perhaps what you've been saying all along..
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-21  2:08                         ` Marin David Condic
@ 2003-02-21 17:27                           ` Jeffrey Carter
  2003-02-22 14:10                             ` Marin David Condic
  2003-02-21 18:02                           ` Warren W. Gay VE3WWG
  1 sibling, 1 reply; 57+ messages in thread
From: Jeffrey Carter @ 2003-02-21 17:27 UTC (permalink / raw)


Marin David Condic wrote:
 > Well, if you use an existing GUI such as Windows or Motif, you are
 > *going* to have callbacks. I'd prefer to isolate them in some kind of
 > wrapper layer and have the "real" app receive messages of some sort.
 > If you were building a GUI from bottom dead center, you could build
 > that sort of thing right in. I'm just saying I think that callbacks
 > are an ugly kludge that I'd prefer were done a different way. You
 > might be able to get there with existing GUIs & glue or wrappers or
 > skins or whatever you like to call it. Just expressing a desire to
 > see an interface to a GUI that doesn't have to know anything about
 > the code *I* write. :-)

This is about what I was trying to say. I mentioned the idea of having a 
task per window to emphasize the inherent concurrency of multiple 
windows, and some posters seem to have fixated on tasks rather than on 
the message (event) queue that was really what I was talking about.

You can see an example of this, built on top of Windows, in JEWL. 
Because it's intended for beginners, it's rather too simple for a 
complete windowing system, but it does show how a GUI can be designed 
using events ("commands" in JEWL parlance) rather than callbacks. It 
doesn't prevent you from having dynamic windows or dialogs, nor does it 
force you to use tasks. It does let you structure your system the way 
you want, and control what it does, rather than structuring it for the 
convenience of the windowing system, and giving control to that system. 
This alone makes the software much easier to read and understand.

-- 
Jeff Carter
"If you don't get the President of the United States on that
phone, ... you're going to have to answer to the Coca-Cola
Company."
Dr. Strangelove




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-21  2:08                         ` Marin David Condic
  2003-02-21 17:27                           ` Jeffrey Carter
@ 2003-02-21 18:02                           ` Warren W. Gay VE3WWG
  2003-02-22 14:49                             ` Marin David Condic
  1 sibling, 1 reply; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-21 18:02 UTC (permalink / raw)


Marin David Condic wrote:
> Well, if you use an existing GUI such as Windows or Motif, you are *going*
> to have callbacks. I'd prefer to isolate them in some kind of wrapper layer
> and have the "real" app receive messages of some sort. If you were building
> a GUI from bottom dead center, you could build that sort of thing right in.
> I'm just saying I think that callbacks are an ugly kludge that I'd prefer
> were done a different way. You might be able to get there with existing GUIs
> & glue or wrappers or skins or whatever you like to call it. Just expressing
> a desire to see an interface to a GUI that doesn't have to know anything
> about the code *I* write. :-)
> 
> MDC

If we were to belabour this discussion a bit further, it seems to me
there are two points worth discussing here:

   1) What is it about callbacks specifically that you don't like?
      I think this needs to be defined beyond "ugly kludge".

   2) What other suitable models are there (with pros/cons)?

The problem that we're dealing with here is an event driven system.
Callbacks are similar to interrupt programming as you've stated.
Outside of the callback (in most GUI apps), you have a main loop
that basically receives events and dispatches them (invoking ultimately
in some cases, callbacks).

The things I dislike about callbacks include:

   1) restricted access to application data (normally just "user data").
   2) each event code is a separate procedure (some may see this as a
      feature).
   3) code restrictions: ie. you must not tarry too long there, or you'll
      hang the main loop (making it not respond to more GUI events).
   4) more code restrictions: sometimes there are some GUI related
      operations that are restricted within a callback (much like malloc()
      is unsafe in a UNIX signal handler).

If we were to move to a task centric model, how would the application
register (link) a task entry (queue) to a specific widget?  It has
been a while since I have played with tasking, so is it possible
(for example) to gain the address of an entry (queue)?  (This is
similar to the idea matching Qt's signals with slots, except we've
introduced a tasking model). Assuming you can't take the address of
a task entry, the only way I can see this working is via a procedure
(callback) that then calls the task entry (a layer proc).

One should note however, that "main loop" hangs are still possible
if you don't plan your task model correctly. For example if one
event takes too long and another comes along before it finishes
(because the user is clicking the button again), the rendezvous
will block until the task is able to accept another request.
To avoid this of course, you could pass off the request to a
separate task, but then you'd have to manage the backlog that an
impatient user might create by hammering a button repeatedly.

I am having a little trouble picturing how this tasking model
can be done, with my limited experience with tasks in Ada.
Would you be able to use a entry "family" number to link
these together dynamically by use of the number? I'll have
to dig out my tasking book tonight.

I am intrigued by this idea.. just trying to picture a practical
implementation of it.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-21 17:27                           ` Jeffrey Carter
@ 2003-02-22 14:10                             ` Marin David Condic
  0 siblings, 0 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-22 14:10 UTC (permalink / raw)


So here's a thing: Ada might potentially be able to evolve some sort of
standard interface to the GUI world by saying "wrap up the GUI in something
that will send and receive this set of messages". I'm curious what sort of
mechanism might provide for a single thread or multiple threads (as you
suggest, a task per window). Either you have the wrapper send things to a
single queue, or you've got to have tasks defining queues and registering
for events. I'm not sure that registering for events is such a bad thing -
I've seen a number of OS-like things that have used this exact scheme and it
works reasonably well. Certainly, if you go to a single queue, one could
evolve yet another layer of abstraction on top of that which would allow for
registration & multiple queues.

Here's a problem though: You could use events/messages/etc or you could use
procedure calls, callbacks, etc., but in either case you've got to have a
lot of things carefully defined and you've got to limit yourself to the
things that could be readily supported by most of the popular GUIs & GUI
builders.Would you see this as a problem? I still like the message/event
format because once you're hiding behind that skin the GUI could be in the
next county and your app doesn't need to know, but I could see it involving
quite a big message catalog & it doesn't get you around
least-common-denominator problems.

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Jeffrey Carter <jrcarter@acm.org> wrote in message
news:3E5661F0.2060200@acm.org...
>
> This is about what I was trying to say. I mentioned the idea of having a
> task per window to emphasize the inherent concurrency of multiple
> windows, and some posters seem to have fixated on tasks rather than on
> the message (event) queue that was really what I was talking about.
>
> You can see an example of this, built on top of Windows, in JEWL.
> Because it's intended for beginners, it's rather too simple for a
> complete windowing system, but it does show how a GUI can be designed
> using events ("commands" in JEWL parlance) rather than callbacks. It
> doesn't prevent you from having dynamic windows or dialogs, nor does it
> force you to use tasks. It does let you structure your system the way
> you want, and control what it does, rather than structuring it for the
> convenience of the windowing system, and giving control to that system.
> This alone makes the software much easier to read and understand.
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-21 18:02                           ` Warren W. Gay VE3WWG
@ 2003-02-22 14:49                             ` Marin David Condic
  2003-02-22 22:50                               ` tmoran
                                                 ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: Marin David Condic @ 2003-02-22 14:49 UTC (permalink / raw)


Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E5669C8.30305@cogeco.ca...
>
> If we were to belabour this discussion a bit further, it seems to me
> there are two points worth discussing here:
>
>    1) What is it about callbacks specifically that you don't like?
>       I think this needs to be defined beyond "ugly kludge".
>
I kind of expressed that in another post. It means that the GUI has intimate
knowledge of my code - much like a computed goto or passing path-flags into
a procedure. It dictates to me what my app must look like (Thou shalt have a
procedure that looks like this and has these parameters and will react in
this way to this event. What if I want to deal with that event in a task?
What if I want one big procedure dealing with 50 different events? What if I
want to run around the office stark naked with a rubber glove on my head
yelling "I'm A Squid! I'm A Squid!" :-) It's none of the GUI's business what
I do or how I choose to do it. It needs to provide me with some sort of
"event" and I need to figure out what to do with it from there.) Callbacks
also start dictating to you that you do things with a particular language -
or at least calling convention. You can write Ada callbacks for C-ish GUIs -
its just painful. I'd prefer something language agnostic and messages are
much more in that realm. I think apps are beter designed when the only thing
they see is the *data* rather than the mechanism by which the data gets
there. Messages/Events are going to be closer to simply reading a data file
than callbacks are going to look like. For those reasons and more, if I were
to invent a GUI from bottom dead center, it wouldn't have a single callback
in it.



>    2) What other suitable models are there (with pros/cons)?
>
Since you're dealing with an "event" of some sort - you've got a kind of
"command/response" protocol - albeit, possibly very asynchronous and loosely
coupled. I've seen a couple of ways of handling that with messages. You
build one big hose and send all the data up and down that hose (a single
queue) or you create some kind of mailbox/post-office kind of thingie where
various threads of an app (or processes in a computer) register for events
they are interested in and  they start receiving them in their mailbox. If
they want to communicate with some other part of the system, they post a
letter via the post office. Both are going to consume a bit more time than a
callback will, but I think thats negligible for most apps. Both require some
level of message management underneath the GUI skin. Both are going to
require that you have some rather large catalog of messages - but no worse
than having a large catalog of callbacks.

Its been done before, so it isn't really radical. I've seen OS's that have
"Events" that an app registers for. I've seen big military systems that have
very complex "postal systems" - sometimes they get unwieldy because the
message traffic is ill defined and the communications are so asynchronous &
uncertain - but for a simple client/server kind of thing its not likely to
be that big a deal.


> The problem that we're dealing with here is an event driven system.
> Callbacks are similar to interrupt programming as you've stated.
> Outside of the callback (in most GUI apps), you have a main loop
> that basically receives events and dispatches them (invoking ultimately
> in some cases, callbacks).
>
See above. An interrupt can be an "event" that results in a message to the
app. You can tie a procedure to an interrupt. You can tie a task entry to an
interrupt. You can have a universal interrupt handler that creates "events"
for the app. All of them work, but "events" are much more like reading a
simple file.


> The things I dislike about callbacks include:
>
>    1) restricted access to application data (normally just "user data").
>    2) each event code is a separate procedure (some may see this as a
>       feature).
>    3) code restrictions: ie. you must not tarry too long there, or you'll
>       hang the main loop (making it not respond to more GUI events).
>    4) more code restrictions: sometimes there are some GUI related
>       operations that are restricted within a callback (much like malloc()
>       is unsafe in a UNIX signal handler).
>
> If we were to move to a task centric model, how would the application
> register (link) a task entry (queue) to a specific widget?  It has
> been a while since I have played with tasking, so is it possible
> (for example) to gain the address of an entry (queue)?  (This is
> similar to the idea matching Qt's signals with slots, except we've
> introduced a tasking model). Assuming you can't take the address of
> a task entry, the only way I can see this working is via a procedure
> (callback) that then calls the task entry (a layer proc).
>
I wouldn't try to hook tasks to the events generated by a widget. That's
just a callback wearing a different suit. I'd create a protocol of messages.
The app starts up and sends to the GUI whatever initialization is required
to get the windows defined & displayed. (A big XML file like what GtkAda
uses to define windows?) The windows and widgets and what have you all have
some kind of identifier associated with them - a unique ID. One or more
tasks want to make something happen, they build a message targeted to the
unique ID of interest and send it to the GUI. The user cliks buttons or
types text or whatever, the widget concerned packages up a message and sends
it (with its ID) to the app. The app just has to figure out what to do with
the messages it gets.

Like I said, the messages to/from the app/GUI might want to be handled by a
"post office" so that individual tasks can decide what events they want to
see, but that's just another layer of abstraction on top of the message
system, so it depends on how complex you want to go.


> One should note however, that "main loop" hangs are still possible
> if you don't plan your task model correctly. For example if one
> event takes too long and another comes along before it finishes
> (because the user is clicking the button again), the rendezvous
> will block until the task is able to accept another request.
> To avoid this of course, you could pass off the request to a
> separate task, but then you'd have to manage the backlog that an
> impatient user might create by hammering a button repeatedly.
>
Don't do that and it will stop hurting. :-) Use messages and decide on what
to do if you start getting duplicate messages or floods of them. Start
dropping them on the floor? The user clicks the button 37 times you react to
it 37 times even if it takes you a while? Handle each widget with its own
task and buy a really massive multiprocessing computer to handle the
thousands of tasks it will have? I think as long as you have a message
protocol, you're free to figure out numerous ways of handling the traffic.


> I am having a little trouble picturing how this tasking model
> can be done, with my limited experience with tasks in Ada.
> Would you be able to use a entry "family" number to link
> these together dynamically by use of the number? I'll have
> to dig out my tasking book tonight.
>
The task starts, it registers for the events it is interested in (opening
files, if you will) and then hangs on some kind of "Receive the next
message" procedure. It quits when it gets the "Shut yourself down" message.
Everything else is some form of case statement or dispatch based on the
message received.


> I am intrigued by this idea.. just trying to picture a practical
> implementation of it.
>
Give it some thought. I think that one might be able to evolve some kind of
low-level wrapper/post-office/client-server thingie that could decouple the
app from the GUI in a way that might allow multiple GUIs and GUI builders to
be working at the other end. It might be worth making some kind of attempt
at a limited prototype to see how it might work in practice.....hmmmmmm

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-22 14:49                             ` Marin David Condic
@ 2003-02-22 22:50                               ` tmoran
  2003-02-23  5:18                               ` Robert C. Leif
  2003-02-24 18:06                               ` Warren W. Gay VE3WWG
  2 siblings, 0 replies; 57+ messages in thread
From: tmoran @ 2003-02-22 22:50 UTC (permalink / raw)


  The "Windows message loop" is a message, rather than callback, oriented
system.  Each "window" (which doesn't have to be a visible screen window,
BTW) is a message queue.  You loop around getting messages and sending
them off to procedures/tasks/whatever to process them.  There are many
different possible messages, each with its own data format.  It does have
the timing latency disadvantages of a polling, rather than interrupt
driven, system, so some stuff (multimedia for instance) is callback
driven.  But most Windows processing involves tasks pulling messages out
of message queues.
  Claw has an internal message loop that turns messages into tagged type
dispatching calls, ie, callbacks.  The callbacks aren't random registered
procedure addresses, but are overrides of objects' primitive procedures.
The result is very much an object, rather than process, noun/adjective
rather than verb, structure.
  Thus instead of a task getting a "mouse moved" msg, which causes it to
call the Recalculate_Wireframe_Projection and then the Display_2D
procedures, say, you design an object (reusable, one hopes) called
Wireframe_Window which is a descendant of Basic_Window and override it's
When_Mousemove procedure with code to recalculate and display given the
new mouse position.  If the app wants to change the object displayed (as
opposed to the screen display) it changes (x,y,z) data, then Invalidates
the Wireframe_Window, thus causing a message to be placed in the message
queue, finally resulting in a call on Wireframe_Window's When_Draw
procedure.  That procedure knows nothing about where the data came from or
how the current mouse position got to where it is, but it does know how to
render the wireframe view of the data given the mouse position.  If you
later decide the 3D display should be red-blue stereo, the changes are
strictly internal to Wireframe_Window.  It's more of a delegated
authority, everyone on the team does his job, style rather than central
command and control.  You tend to think more in terms of goals than
actions, eg, "set a course due North" rather than "turn the wheel to the
port, then straighten it when the ship is traveling due North".  Not
"Do this then that" but "Make it so".



^ permalink raw reply	[flat|nested] 57+ messages in thread

* RE: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-22 14:49                             ` Marin David Condic
  2003-02-22 22:50                               ` tmoran
@ 2003-02-23  5:18                               ` Robert C. Leif
  2003-02-24 18:06                               ` Warren W. Gay VE3WWG
  2 siblings, 0 replies; 57+ messages in thread
From: Robert C. Leif @ 2003-02-23  5:18 UTC (permalink / raw)
  To: 'comp.lang.ada mail to news gateway'

Marin Condic wrote, "Give it some thought. I think that one might be able to
evolve some kind of low-level wrapper/post-office/client-server thingie that
could decouple the app from the GUI in a way that might allow multiple GUIs
and GUI builders to be working at the other end."
I suspect that this "thingie" could be an extensible protected type. It
would be a combination of a tagged and a protected type. It was suggested at
SIGAda 02 that this construct would be very useful for real-time code.
I hope that one of the Ada language experts who attended SIGAda might
comment on this.
Bob Leif

-----Original Message-----
From: Marin David Condic [mailto:mcondic.auntie.spam@acm.org] 
Sent: Saturday, February 22, 2003 6:50 AM
To: comp.lang.ada@ada.eu.org
Subject: Re: [OT] Best way to isolate a GUI? (The final concensous?)

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E5669C8.30305@cogeco.ca...
>
> If we were to belabour this discussion a bit further, it seems to me
> there are two points worth discussing here:
>
>    1) What is it about callbacks specifically that you don't like?
>       I think this needs to be defined beyond "ugly kludge".
>
I kind of expressed that in another post. It means that the GUI has intimate
knowledge of my code - much like a computed goto or passing path-flags into
a procedure. It dictates to me what my app must look like (Thou shalt have a
procedure that looks like this and has these parameters and will react in
this way to this event. What if I want to deal with that event in a task?
What if I want one big procedure dealing with 50 different events? What if I
want to run around the office stark naked with a rubber glove on my head
yelling "I'm A Squid! I'm A Squid!" :-) It's none of the GUI's business what
I do or how I choose to do it. It needs to provide me with some sort of
"event" and I need to figure out what to do with it from there.) Callbacks
also start dictating to you that you do things with a particular language -
or at least calling convention. You can write Ada callbacks for C-ish GUIs -
its just painful. I'd prefer something language agnostic and messages are
much more in that realm. I think apps are beter designed when the only thing
they see is the *data* rather than the mechanism by which the data gets
there. Messages/Events are going to be closer to simply reading a data file
than callbacks are going to look like. For those reasons and more, if I were
to invent a GUI from bottom dead center, it wouldn't have a single callback
in it.



>    2) What other suitable models are there (with pros/cons)?
>
Since you're dealing with an "event" of some sort - you've got a kind of
"command/response" protocol - albeit, possibly very asynchronous and loosely
coupled. I've seen a couple of ways of handling that with messages. You
build one big hose and send all the data up and down that hose (a single
queue) or you create some kind of mailbox/post-office kind of thingie where
various threads of an app (or processes in a computer) register for events
they are interested in and  they start receiving them in their mailbox. If
they want to communicate with some other part of the system, they post a
letter via the post office. Both are going to consume a bit more time than a
callback will, but I think thats negligible for most apps. Both require some
level of message management underneath the GUI skin. Both are going to
require that you have some rather large catalog of messages - but no worse
than having a large catalog of callbacks.

Its been done before, so it isn't really radical. I've seen OS's that have
"Events" that an app registers for. I've seen big military systems that have
very complex "postal systems" - sometimes they get unwieldy because the
message traffic is ill defined and the communications are so asynchronous &
uncertain - but for a simple client/server kind of thing its not likely to
be that big a deal.


> The problem that we're dealing with here is an event driven system.
> Callbacks are similar to interrupt programming as you've stated.
> Outside of the callback (in most GUI apps), you have a main loop
> that basically receives events and dispatches them (invoking ultimately
> in some cases, callbacks).
>
See above. An interrupt can be an "event" that results in a message to the
app. You can tie a procedure to an interrupt. You can tie a task entry to an
interrupt. You can have a universal interrupt handler that creates "events"
for the app. All of them work, but "events" are much more like reading a
simple file.


> The things I dislike about callbacks include:
>
>    1) restricted access to application data (normally just "user data").
>    2) each event code is a separate procedure (some may see this as a
>       feature).
>    3) code restrictions: ie. you must not tarry too long there, or you'll
>       hang the main loop (making it not respond to more GUI events).
>    4) more code restrictions: sometimes there are some GUI related
>       operations that are restricted within a callback (much like malloc()
>       is unsafe in a UNIX signal handler).
>
> If we were to move to a task centric model, how would the application
> register (link) a task entry (queue) to a specific widget?  It has
> been a while since I have played with tasking, so is it possible
> (for example) to gain the address of an entry (queue)?  (This is
> similar to the idea matching Qt's signals with slots, except we've
> introduced a tasking model). Assuming you can't take the address of
> a task entry, the only way I can see this working is via a procedure
> (callback) that then calls the task entry (a layer proc).
>
I wouldn't try to hook tasks to the events generated by a widget. That's
just a callback wearing a different suit. I'd create a protocol of messages.
The app starts up and sends to the GUI whatever initialization is required
to get the windows defined & displayed. (A big XML file like what GtkAda
uses to define windows?) The windows and widgets and what have you all have
some kind of identifier associated with them - a unique ID. One or more
tasks want to make something happen, they build a message targeted to the
unique ID of interest and send it to the GUI. The user cliks buttons or
types text or whatever, the widget concerned packages up a message and sends
it (with its ID) to the app. The app just has to figure out what to do with
the messages it gets.

Like I said, the messages to/from the app/GUI might want to be handled by a
"post office" so that individual tasks can decide what events they want to
see, but that's just another layer of abstraction on top of the message
system, so it depends on how complex you want to go.


> One should note however, that "main loop" hangs are still possible
> if you don't plan your task model correctly. For example if one
> event takes too long and another comes along before it finishes
> (because the user is clicking the button again), the rendezvous
> will block until the task is able to accept another request.
> To avoid this of course, you could pass off the request to a
> separate task, but then you'd have to manage the backlog that an
> impatient user might create by hammering a button repeatedly.
>
Don't do that and it will stop hurting. :-) Use messages and decide on what
to do if you start getting duplicate messages or floods of them. Start
dropping them on the floor? The user clicks the button 37 times you react to
it 37 times even if it takes you a while? Handle each widget with its own
task and buy a really massive multiprocessing computer to handle the
thousands of tasks it will have? I think as long as you have a message
protocol, you're free to figure out numerous ways of handling the traffic.


> I am having a little trouble picturing how this tasking model
> can be done, with my limited experience with tasks in Ada.
> Would you be able to use a entry "family" number to link
> these together dynamically by use of the number? I'll have
> to dig out my tasking book tonight.
>
The task starts, it registers for the events it is interested in (opening
files, if you will) and then hangs on some kind of "Receive the next
message" procedure. It quits when it gets the "Shut yourself down" message.
Everything else is some form of case statement or dispatch based on the
message received.


> I am intrigued by this idea.. just trying to picture a practical
> implementation of it.
>
Give it some thought. I think that one might be able to evolve some kind of
low-level wrapper/post-office/client-server thingie that could decouple the
app from the GUI in a way that might allow multiple GUIs and GUI builders to
be working at the other end. It might be worth making some kind of attempt
at a limited prototype to see how it might work in practice.....hmmmmmm

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================







^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-22 14:49                             ` Marin David Condic
  2003-02-22 22:50                               ` tmoran
  2003-02-23  5:18                               ` Robert C. Leif
@ 2003-02-24 18:06                               ` Warren W. Gay VE3WWG
  2003-02-25  1:20                                 ` Robert C. Leif
  2003-02-25 12:41                                 ` Marin David Condic
  2 siblings, 2 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-24 18:06 UTC (permalink / raw)


Unfortunately I have to be a bit brief in this reply (shortened
lunch today ;-)

Marin David Condic wrote:
> Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
> news:3E5669C8.30305@cogeco.ca...
> 
...
>>If we were to move to a task centric model, how would the application
>>register (link) a task entry (queue) to a specific widget?  It has
>>been a while since I have played with tasking, so is it possible
>>(for example) to gain the address of an entry (queue)?  (This is
>>similar to the idea matching Qt's signals with slots, except we've
>>introduced a tasking model). Assuming you can't take the address of
>>a task entry, the only way I can see this working is via a procedure
>>(callback) that then calls the task entry (a layer proc).
>>
> 
> I wouldn't try to hook tasks to the events generated by a widget. That's
> just a callback wearing a different suit. I'd create a protocol of messages.
> The app starts up and sends to the GUI whatever initialization is required
> to get the windows defined & displayed. (A big XML file like what GtkAda
> uses to define windows?) The windows and widgets and what have you all have
> some kind of identifier associated with them - a unique ID. One or more
> tasks want to make something happen, they build a message targeted to the
> unique ID of interest and send it to the GUI. The user cliks buttons or
> types text or whatever, the widget concerned packages up a message and sends
> it (with its ID) to the app. The app just has to figure out what to do with
> the messages it gets.
> 
> Like I said, the messages to/from the app/GUI might want to be handled by a
> "post office" so that individual tasks can decide what events they want to
> see, but that's just another layer of abstraction on top of the message
> system, so it depends on how complex you want to go.

Having given it some thought over the weekend, and after review that
fine book "Concurrency in Ada" (or something like that), I'll just
quickly summarize some of the issues that occurred to me:

1. Event queues don't work well, unless you've defined some way of
    "returning event data".  By this, consider a "verify" widget event,
    where you want to provide a callback to perform a user verification
    on some text input widget. The verify event must return a VALID
    or NOT_VALID response.

    Callbacks perform this easily, because by appropriate use of in/out
    arguments, you can plan for returned data.

    For event queue's, the data is "one way". This is not to say that it
    is unsolvable, just perhaps "inconvenient".

2. A bi-directional "pipe" introduces other problems like latency,
    and sequencing (like two pieces of code returning different values).

3. If more than one task once notice of an event, then you need to allow
    for "multicasting" the event (simple with callback lists).

    If you use a protected object, for "multicasting" as is done in
    the "Concurrency in Ada" book, then like the message queue, you still
    have the "return data" problem. The added problem here is that now
    you have a certain amount of new "indeterminism" added to the mix,
    because the multicasting may multicast in a different sequence,
    according to timing.

    Of course this is fixable, because it can be serialized, but it does
    add some complexity, and perhaps some inefficiency as well.

>>One should note however, that "main loop" hangs are still possible
>>if you don't plan your task model correctly. For example if one
>>event takes too long and another comes along before it finishes
>>(because the user is clicking the button again), the rendezvous
>>will block until the task is able to accept another request.
>>To avoid this of course, you could pass off the request to a
>>separate task, but then you'd have to manage the backlog that an
>>impatient user might create by hammering a button repeatedly.
> 
> Don't do that and it will stop hurting. :-) 

Of course, but apply a young kid to a mouse, and let him click
away, and it is amazing how many GUI systems/applications come
crashing to its knees!  Yes, I know.. keep kids away from the mouse!

> Use messages and decide on what
> to do if you start getting duplicate messages or floods of them. Start
> dropping them on the floor? The user clicks the button 37 times you react to
> it 37 times even if it takes you a while? Handle each widget with its own
> task and buy a really massive multiprocessing computer to handle the
> thousands of tasks it will have? I think as long as you have a message
> protocol, you're free to figure out numerous ways of handling the traffic.

Of course, these are all solvable problems. But some of these
problems are easier to solve in some frameworks, rather than
others (at least it must be considered).

>>I am having a little trouble picturing how this tasking model
>>can be done, with my limited experience with tasks in Ada.
>>Would you be able to use a entry "family" number to link
>>these together dynamically by use of the number? I'll have
>>to dig out my tasking book tonight.
> 
> The task starts, it registers for the events it is interested in (opening
> files, if you will) and then hangs on some kind of "Receive the next
> message" procedure. It quits when it gets the "Shut yourself down" message.
> Everything else is some form of case statement or dispatch based on the
> message received.

OK, but this act of "registering for events" is either going to
return a handle to a queue or protected object acting as such.

But your model considers events as a one way message flow, which is
clean and simple. But it doesn't address the verify callback
scenario, which is but one example of where data needs to be
returned (consider that once a verify has failed, there is no
need to call other verify callbacks for example).

This is not unsolvable, but it seems rather inconvenient and
open to other problems.

>>I am intrigued by this idea.. just trying to picture a practical
>>implementation of it.
> 
> Give it some thought. I think that one might be able to evolve some kind of
> low-level wrapper/post-office/client-server thingie that could decouple the
> app from the GUI in a way that might allow multiple GUIs and GUI builders to
> be working at the other end. It might be worth making some kind of attempt
> at a limited prototype to see how it might work in practice.....hmmmmmm
> 
> MDC

I think it is a worthy goal, but present musings don't seem
all that practical when I consider some of the problems that
come up.  Maybe we just need a better model ;-)

My lunch time is over... I'll have to ponder this more later.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* RE: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-24 18:06                               ` Warren W. Gay VE3WWG
@ 2003-02-25  1:20                                 ` Robert C. Leif
  2003-02-25 17:57                                   ` Warren W. Gay VE3WWG
  2003-02-25 12:41                                 ` Marin David Condic
  1 sibling, 1 reply; 57+ messages in thread
From: Robert C. Leif @ 2003-02-25  1:20 UTC (permalink / raw)
  To: 'comp.lang.ada mail to news gateway'

Warren W. Gay wrote:
"If more than one task once notice of an event, then you need to allow
    for "multicasting" the event (simple with callback lists).

    If you use a protected object, for "multicasting" as is done in
    the "Concurrency in Ada" book, then like the message queue, you still
    have the "return data" problem. The added problem here is that now
    you have a certain amount of new "indeterminism" added to the mix,
    because the multicasting may multicast in a different sequence,
    according to timing.

    Of course this is fixable, because it can be serialized, but it does
    add some complexity, and perhaps some inefficiency as well."

However, only one procedure can write to the web page. Multiple functions
can read the page. Since an XML web page often contains data, this is an
appropriate mode of protection. Since CLAW is an example of the utility of
tagged types for windows, an appropriate combination of a protected and
tagged type (Ada 200Y) could provide a solution based on Ada. Hopefully,
this would either reduce the use of pointers or eliminate their use. 
Two interesting questions are could an XML paging system be written in SPARK
or employ the Ravenscar profile? Would this increase the security of the
system?
Bob Leif


-----Original Message-----
From: Warren W. Gay VE3WWG [mailto:ve3wwg@cogeco.ca] 
Sent: Monday, February 24, 2003 10:06 AM
To: comp.lang.ada@ada.eu.org
Subject: Re: [OT] Best way to isolate a GUI? (The final concensous?)

Unfortunately I have to be a bit brief in this reply (shortened
lunch today ;-)

Marin David Condic wrote:
> Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
> news:3E5669C8.30305@cogeco.ca...
> 
...
>>If we were to move to a task centric model, how would the application
>>register (link) a task entry (queue) to a specific widget?  It has
>>been a while since I have played with tasking, so is it possible
>>(for example) to gain the address of an entry (queue)?  (This is
>>similar to the idea matching Qt's signals with slots, except we've
>>introduced a tasking model). Assuming you can't take the address of
>>a task entry, the only way I can see this working is via a procedure
>>(callback) that then calls the task entry (a layer proc).
>>
> 
> I wouldn't try to hook tasks to the events generated by a widget. That's
> just a callback wearing a different suit. I'd create a protocol of
messages.
> The app starts up and sends to the GUI whatever initialization is required
> to get the windows defined & displayed. (A big XML file like what GtkAda
> uses to define windows?) The windows and widgets and what have you all
have
> some kind of identifier associated with them - a unique ID. One or more
> tasks want to make something happen, they build a message targeted to the
> unique ID of interest and send it to the GUI. The user cliks buttons or
> types text or whatever, the widget concerned packages up a message and
sends
> it (with its ID) to the app. The app just has to figure out what to do
with
> the messages it gets.
> 
> Like I said, the messages to/from the app/GUI might want to be handled by
a
> "post office" so that individual tasks can decide what events they want to
> see, but that's just another layer of abstraction on top of the message
> system, so it depends on how complex you want to go.

Having given it some thought over the weekend, and after review that
fine book "Concurrency in Ada" (or something like that), I'll just
quickly summarize some of the issues that occurred to me:

1. Event queues don't work well, unless you've defined some way of
    "returning event data".  By this, consider a "verify" widget event,
    where you want to provide a callback to perform a user verification
    on some text input widget. The verify event must return a VALID
    or NOT_VALID response.

    Callbacks perform this easily, because by appropriate use of in/out
    arguments, you can plan for returned data.

    For event queue's, the data is "one way". This is not to say that it
    is unsolvable, just perhaps "inconvenient".

2. A bi-directional "pipe" introduces other problems like latency,
    and sequencing (like two pieces of code returning different values).

3. If more than one task once notice of an event, then you need to allow
    for "multicasting" the event (simple with callback lists).

    If you use a protected object, for "multicasting" as is done in
    the "Concurrency in Ada" book, then like the message queue, you still
    have the "return data" problem. The added problem here is that now
    you have a certain amount of new "indeterminism" added to the mix,
    because the multicasting may multicast in a different sequence,
    according to timing.

    Of course this is fixable, because it can be serialized, but it does
    add some complexity, and perhaps some inefficiency as well.

>>One should note however, that "main loop" hangs are still possible
>>if you don't plan your task model correctly. For example if one
>>event takes too long and another comes along before it finishes
>>(because the user is clicking the button again), the rendezvous
>>will block until the task is able to accept another request.
>>To avoid this of course, you could pass off the request to a
>>separate task, but then you'd have to manage the backlog that an
>>impatient user might create by hammering a button repeatedly.
> 
> Don't do that and it will stop hurting. :-) 

Of course, but apply a young kid to a mouse, and let him click
away, and it is amazing how many GUI systems/applications come
crashing to its knees!  Yes, I know.. keep kids away from the mouse!

> Use messages and decide on what
> to do if you start getting duplicate messages or floods of them. Start
> dropping them on the floor? The user clicks the button 37 times you react
to
> it 37 times even if it takes you a while? Handle each widget with its own
> task and buy a really massive multiprocessing computer to handle the
> thousands of tasks it will have? I think as long as you have a message
> protocol, you're free to figure out numerous ways of handling the traffic.

Of course, these are all solvable problems. But some of these
problems are easier to solve in some frameworks, rather than
others (at least it must be considered).

>>I am having a little trouble picturing how this tasking model
>>can be done, with my limited experience with tasks in Ada.
>>Would you be able to use a entry "family" number to link
>>these together dynamically by use of the number? I'll have
>>to dig out my tasking book tonight.
> 
> The task starts, it registers for the events it is interested in (opening
> files, if you will) and then hangs on some kind of "Receive the next
> message" procedure. It quits when it gets the "Shut yourself down"
message.
> Everything else is some form of case statement or dispatch based on the
> message received.

OK, but this act of "registering for events" is either going to
return a handle to a queue or protected object acting as such.

But your model considers events as a one way message flow, which is
clean and simple. But it doesn't address the verify callback
scenario, which is but one example of where data needs to be
returned (consider that once a verify has failed, there is no
need to call other verify callbacks for example).

This is not unsolvable, but it seems rather inconvenient and
open to other problems.

>>I am intrigued by this idea.. just trying to picture a practical
>>implementation of it.
> 
> Give it some thought. I think that one might be able to evolve some kind
of
> low-level wrapper/post-office/client-server thingie that could decouple
the
> app from the GUI in a way that might allow multiple GUIs and GUI builders
to
> be working at the other end. It might be worth making some kind of attempt
> at a limited prototype to see how it might work in practice.....hmmmmmm
> 
> MDC

I think it is a worthy goal, but present musings don't seem
all that practical when I consider some of the problems that
come up.  Maybe we just need a better model ;-)

My lunch time is over... I'll have to ponder this more later.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg





^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-24 18:06                               ` Warren W. Gay VE3WWG
  2003-02-25  1:20                                 ` Robert C. Leif
@ 2003-02-25 12:41                                 ` Marin David Condic
  2003-02-25 13:32                                   ` Ole-Hjalmar Kristensen
  1 sibling, 1 reply; 57+ messages in thread
From: Marin David Condic @ 2003-02-25 12:41 UTC (permalink / raw)


I understand your concerns - especially about returning data and potential
indeterminism. A lot of that is why messaging systems get limited to a
command/response protocol - so that you do have returned data and you force
some serialization into the process. Some messaging systems include things
like heartbeat counters or other numbering schemes to try to insure that
things line up nicely and that failures are handled, specifically to try to
get away from the problems you cite.

Ultimately, it comes down to this: You want to design something, you'll have
to pick some philosophy or approach. Having done that, you just eliminated
all the other possible approaches. That means you'll always be able to stand
there looking at the design you *did* pick and cast stones at it because it
doesn't have the strengths of some other approach. If you do that enough,
you never accomplish anything. So you try to pick the dog with the least
number of fleas.

In my little imaginary world of dreaming up a way to separate the GUI from
the app, I tend to like a messaging scheme because it is loosely coupled and
flexible enough that it could probably be mated to a number of GUIs and GUI
builders as well as staying language neutral. I think if one went another
route - that involving callbacks - one would likely lose the flexibility and
find it difficult to make it line up with more than one GUI at a time. While
callbacks are going to have certain advantages (forcing a certain amount of
command/response protocol and returning results to the GUI) I think that
careful design of a messaging system might be able to live without those
advantages or synthesize them in some other way. So you pays your money and
you takes your pick. :-)

MDC
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/

Send Replies To: m c o n d i c @ a c m . o r g

    "Going cold turkey isn't as delicious as it sounds."
        -- H. Simpson
======================================================================

Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
news:3E5A5F1C.9040907@cogeco.ca...
> Unfortunately I have to be a bit brief in this reply (shortened
> lunch today ;-)
>






^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-25 12:41                                 ` Marin David Condic
@ 2003-02-25 13:32                                   ` Ole-Hjalmar Kristensen
  2003-02-25 17:33                                     ` [OT] Best way to isolate a GUI? (The final fronteer?) Warren W. Gay VE3WWG
  0 siblings, 1 reply; 57+ messages in thread
From: Ole-Hjalmar Kristensen @ 2003-02-25 13:32 UTC (permalink / raw)


"Marin David Condic" <mcondic.auntie.spam@acm.org> writes:

<snip>

> In my little imaginary world of dreaming up a way to separate the GUI from
> the app, I tend to like a messaging scheme because it is loosely coupled and
> flexible enough that it could probably be mated to a number of GUIs and GUI
> builders as well as staying language neutral. I think if one went another

That's one of the reasons the interface to the X window system server is actually
defined as a network protocol.

> route - that involving callbacks - one would likely lose the flexibility and
> find it difficult to make it line up with more than one GUI at a time. While
> callbacks are going to have certain advantages (forcing a certain amount of
> command/response protocol and returning results to the GUI) I think that
> careful design of a messaging system might be able to live without those
> advantages or synthesize them in some other way. So you pays your money and
> you takes your pick. :-)

-- 
Ole-Hj. Kristensen

******************************************************************************
* You cannot consistently believe this sentence.
******************************************************************************



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final fronteer?)
  2003-02-25 13:32                                   ` Ole-Hjalmar Kristensen
@ 2003-02-25 17:33                                     ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-25 17:33 UTC (permalink / raw)


Ole-Hjalmar Kristensen wrote:
> "Marin David Condic" <mcondic.auntie.spam@acm.org> writes:
> 
> <snip>
> 
>>In my little imaginary world of dreaming up a way to separate the GUI from
>>the app, I tend to like a messaging scheme because it is loosely coupled and
>>flexible enough that it could probably be mated to a number of GUIs and GUI
>>builders as well as staying language neutral. I think if one went another
> 
> 
> That's one of the reasons the interface to the X window system server is actually
> defined as a network protocol.

Note however, that these messages have serial numbers for serialization
and error checking purposes. However, if you check most X Window
programs, error checking is effectively non-existant. The reason for
this is that the status coming back, comes much later than the request
(the application normally allows new requests to be issued before the
status comes back).

While errors can be checked and reacted to well after the fact, it
becomes rather impractical in most applications.  The problem is that
once an error is detected, you have to consider what other operations have
just been requested, how many of them succeeded, and how many are still
on their way to the server.

To avoid this, you can have the X Window system work in a synchronous
type of mode (I forget the name of this call that controls this), but
the performance is so bad that most apps have this off by default, or
turn it off when required.

So when one considers a design, you must always look at all sides
of it, because there are many practical considerations getting in
the way of the "ideal", unfortunately.

>>route - that involving callbacks - one would likely lose the flexibility and
>>find it difficult to make it line up with more than one GUI at a time. While
>>callbacks are going to have certain advantages (forcing a certain amount of
>>command/response protocol and returning results to the GUI) I think that
>>careful design of a messaging system might be able to live without those
>>advantages or synthesize them in some other way. So you pays your money and
>>you takes your pick. :-)

I agree that one should always be questioning the
"accepted world" in technical terms (in this case callbacks).
Only by doing this are new techniques or discoveries made.

However, on this one, I don't think we're quite there yet ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Best way to isolate a GUI? (The final concensous?)
  2003-02-25  1:20                                 ` Robert C. Leif
@ 2003-02-25 17:57                                   ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 57+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-02-25 17:57 UTC (permalink / raw)


Robert C. Leif wrote:
> Warren W. Gay wrote:
> "If more than one task once notice of an event, then you need to allow
>     for "multicasting" the event (simple with callback lists).
> 
>     If you use a protected object, for "multicasting" as is done in
>     the "Concurrency in Ada" book, then like the message queue, you still
>     have the "return data" problem. The added problem here is that now
>     you have a certain amount of new "indeterminism" added to the mix,
>     because the multicasting may multicast in a different sequence,
>     according to timing.
> 
>     Of course this is fixable, because it can be serialized, but it does
>     add some complexity, and perhaps some inefficiency as well."
> 
> However, only one procedure can write to the web page. Multiple functions
> can read the page. Since an XML web page often contains data, this is an
> appropriate mode of protection. 

I don't understand the point that you making here. I don't have an
issue with multicasting per se. I am just suggesting that one must
allow for "return data" for use in some events (not all events are
one way information transfers).

> Since CLAW is an example of the utility of
> tagged types for windows, an appropriate combination of a protected and
> tagged type (Ada 200Y) could provide a solution based on Ada. Hopefully,
> this would either reduce the use of pointers or eliminate their use. 

I don't understand what any of this has to do with what is being
discussed.

> Two interesting questions are could an XML paging system be written in SPARK
> or employ the Ravenscar profile? Would this increase the security of the
> system?
> Bob Leif

I must be missing something, because I see no connection here.

Warren.

> -----Original Message-----
> From: Warren W. Gay VE3WWG [mailto:ve3wwg@cogeco.ca] 
> Sent: Monday, February 24, 2003 10:06 AM
> To: comp.lang.ada@ada.eu.org
> Subject: Re: [OT] Best way to isolate a GUI? (The final concensous?)
> 
> Unfortunately I have to be a bit brief in this reply (shortened
> lunch today ;-)
> 
> Marin David Condic wrote:
> 
>>Warren W. Gay VE3WWG <ve3wwg@cogeco.ca> wrote in message
>>news:3E5669C8.30305@cogeco.ca...
>>
> 
> ....
> 
>>>If we were to move to a task centric model, how would the application
>>>register (link) a task entry (queue) to a specific widget?  It has
>>>been a while since I have played with tasking, so is it possible
>>>(for example) to gain the address of an entry (queue)?  (This is
>>>similar to the idea matching Qt's signals with slots, except we've
>>>introduced a tasking model). Assuming you can't take the address of
>>>a task entry, the only way I can see this working is via a procedure
>>>(callback) that then calls the task entry (a layer proc).
>>>
>>
>>I wouldn't try to hook tasks to the events generated by a widget. That's
>>just a callback wearing a different suit. I'd create a protocol of
> 
> messages.
> 
>>The app starts up and sends to the GUI whatever initialization is required
>>to get the windows defined & displayed. (A big XML file like what GtkAda
>>uses to define windows?) The windows and widgets and what have you all
> 
> have
> 
>>some kind of identifier associated with them - a unique ID. One or more
>>tasks want to make something happen, they build a message targeted to the
>>unique ID of interest and send it to the GUI. The user cliks buttons or
>>types text or whatever, the widget concerned packages up a message and
> 
> sends
> 
>>it (with its ID) to the app. The app just has to figure out what to do
> 
> with
> 
>>the messages it gets.
>>
>>Like I said, the messages to/from the app/GUI might want to be handled by
> 
> a
> 
>>"post office" so that individual tasks can decide what events they want to
>>see, but that's just another layer of abstraction on top of the message
>>system, so it depends on how complex you want to go.
> 
> 
> Having given it some thought over the weekend, and after review that
> fine book "Concurrency in Ada" (or something like that), I'll just
> quickly summarize some of the issues that occurred to me:
> 
> 1. Event queues don't work well, unless you've defined some way of
>     "returning event data".  By this, consider a "verify" widget event,
>     where you want to provide a callback to perform a user verification
>     on some text input widget. The verify event must return a VALID
>     or NOT_VALID response.
> 
>     Callbacks perform this easily, because by appropriate use of in/out
>     arguments, you can plan for returned data.
> 
>     For event queue's, the data is "one way". This is not to say that it
>     is unsolvable, just perhaps "inconvenient".
> 
> 2. A bi-directional "pipe" introduces other problems like latency,
>     and sequencing (like two pieces of code returning different values).
> 
> 3. If more than one task once notice of an event, then you need to allow
>     for "multicasting" the event (simple with callback lists).
> 
>     If you use a protected object, for "multicasting" as is done in
>     the "Concurrency in Ada" book, then like the message queue, you still
>     have the "return data" problem. The added problem here is that now
>     you have a certain amount of new "indeterminism" added to the mix,
>     because the multicasting may multicast in a different sequence,
>     according to timing.
> 
>     Of course this is fixable, because it can be serialized, but it does
>     add some complexity, and perhaps some inefficiency as well.
> 
> 
>>>One should note however, that "main loop" hangs are still possible
>>>if you don't plan your task model correctly. For example if one
>>>event takes too long and another comes along before it finishes
>>>(because the user is clicking the button again), the rendezvous
>>>will block until the task is able to accept another request.
>>>To avoid this of course, you could pass off the request to a
>>>separate task, but then you'd have to manage the backlog that an
>>>impatient user might create by hammering a button repeatedly.
>>
>>Don't do that and it will stop hurting. :-) 
> 
> 
> Of course, but apply a young kid to a mouse, and let him click
> away, and it is amazing how many GUI systems/applications come
> crashing to its knees!  Yes, I know.. keep kids away from the mouse!
> 
> 
>>Use messages and decide on what
>>to do if you start getting duplicate messages or floods of them. Start
>>dropping them on the floor? The user clicks the button 37 times you react
> 
> to
> 
>>it 37 times even if it takes you a while? Handle each widget with its own
>>task and buy a really massive multiprocessing computer to handle the
>>thousands of tasks it will have? I think as long as you have a message
>>protocol, you're free to figure out numerous ways of handling the traffic.
> 
> 
> Of course, these are all solvable problems. But some of these
> problems are easier to solve in some frameworks, rather than
> others (at least it must be considered).
> 
> 
>>>I am having a little trouble picturing how this tasking model
>>>can be done, with my limited experience with tasks in Ada.
>>>Would you be able to use a entry "family" number to link
>>>these together dynamically by use of the number? I'll have
>>>to dig out my tasking book tonight.
>>
>>The task starts, it registers for the events it is interested in (opening
>>files, if you will) and then hangs on some kind of "Receive the next
>>message" procedure. It quits when it gets the "Shut yourself down"
> 
> message.
> 
>>Everything else is some form of case statement or dispatch based on the
>>message received.
> 
> 
> OK, but this act of "registering for events" is either going to
> return a handle to a queue or protected object acting as such.
> 
> But your model considers events as a one way message flow, which is
> clean and simple. But it doesn't address the verify callback
> scenario, which is but one example of where data needs to be
> returned (consider that once a verify has failed, there is no
> need to call other verify callbacks for example).
> 
> This is not unsolvable, but it seems rather inconvenient and
> open to other problems.
> 
> 
>>>I am intrigued by this idea.. just trying to picture a practical
>>>implementation of it.
>>
>>Give it some thought. I think that one might be able to evolve some kind
> 
> of
> 
>>low-level wrapper/post-office/client-server thingie that could decouple
> 
> the
> 
>>app from the GUI in a way that might allow multiple GUIs and GUI builders
> 
> to
> 
>>be working at the other end. It might be worth making some kind of attempt
>>at a limited prototype to see how it might work in practice.....hmmmmmm
>>
>>MDC
> 
> 
> I think it is a worthy goal, but present musings don't seem
> all that practical when I consider some of the problems that
> come up.  Maybe we just need a better model ;-)
> 
> My lunch time is over... I'll have to ponder this more later.
> 


-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2003-02-25 17:57 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-16 10:19 [OT] Best way to isolate a GUI? Jano
2003-02-16 14:47 ` Ed Falis
2003-02-16 14:49 ` Victor Porton
2003-02-17 20:52   ` Jano
2003-02-16 16:36 ` Robert C. Leif
2003-02-17  8:44   ` Preben Randhol
2003-02-17 16:22     ` Robert C. Leif
2003-02-17 17:30     ` Jeffrey Carter
2003-02-17 17:54       ` Warren W. Gay VE3WWG
2003-02-17 19:06         ` Randy Brukardt
2003-02-18  3:15           ` Warren W. Gay VE3WWG
2003-02-18 16:14             ` Robert C. Leif
2003-02-18 18:10             ` Randy Brukardt
2003-02-18 21:12               ` Warren W. Gay VE3WWG
2003-02-18 23:20                 ` Randy Brukardt
2003-02-19 18:28                   ` Warren W. Gay VE3WWG
2003-02-20 19:39                     ` Randy Brukardt
2003-02-20 21:34                       ` Warren W. Gay VE3WWG
2003-02-20  7:50                   ` Dale Stanbrough
2003-02-19 12:49                 ` Marin David Condic
2003-02-19 18:35                   ` [OT] Best way to isolate a GUI? (The final concensous?) Warren W. Gay VE3WWG
2003-02-20 12:40                     ` Marin David Condic
2003-02-20 13:13                       ` Dmitry A. Kazakov
2003-02-20 22:01                       ` Warren W. Gay VE3WWG
2003-02-21  1:25                         ` tmoran
2003-02-21  2:08                         ` Marin David Condic
2003-02-21 17:27                           ` Jeffrey Carter
2003-02-22 14:10                             ` Marin David Condic
2003-02-21 18:02                           ` Warren W. Gay VE3WWG
2003-02-22 14:49                             ` Marin David Condic
2003-02-22 22:50                               ` tmoran
2003-02-23  5:18                               ` Robert C. Leif
2003-02-24 18:06                               ` Warren W. Gay VE3WWG
2003-02-25  1:20                                 ` Robert C. Leif
2003-02-25 17:57                                   ` Warren W. Gay VE3WWG
2003-02-25 12:41                                 ` Marin David Condic
2003-02-25 13:32                                   ` Ole-Hjalmar Kristensen
2003-02-25 17:33                                     ` [OT] Best way to isolate a GUI? (The final fronteer?) Warren W. Gay VE3WWG
2003-02-20  8:26                   ` [OT] Best way to isolate a GUI? tmoran
2003-02-20 12:51                     ` Marin David Condic
2003-02-20 18:47                       ` tmoran
2003-02-17 19:31         ` tmoran
2003-02-18  1:37         ` Jeffrey Carter
2003-02-18  3:39           ` Warren W. Gay VE3WWG
2003-02-18 23:36           ` Randy Brukardt
2003-02-18 13:29         ` Marin David Condic
2003-02-18 18:01           ` Warren W. Gay VE3WWG
2003-02-19 13:06             ` Marin David Condic
2003-02-16 17:25 ` achrist
2003-02-16 21:24 ` Bobby D. Bryant
2003-02-16 21:52 ` David Marceau
2003-02-17  0:57 ` Re; " tmoran
2003-02-17  7:25   ` Jano
2003-02-17 14:09     ` Bobby D. Bryant
2003-02-17 21:12       ` Jano
2003-02-18  7:24         ` Jean-Pierre Rosen
2003-02-18 13:08 ` Marin David Condic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox