* [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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ 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; 62+ 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] 62+ messages in thread
* RE: Re; [OT] Best way to isolate a GUI? @ 2003-02-18 10:26 Lionel.DRAGHI 0 siblings, 0 replies; 62+ messages in thread From: Lionel.DRAGHI @ 2003-02-18 10:26 UTC (permalink / raw) To: comp.lang.ada | -----Message d'origine----- | De: Jano [mailto:402450@cepsz.unizar.es] ... | | One GUI proccess could be a web server (AWS), or could be a | GtkAda GUI, | or whatever. But that's the point. | | Thoughts? IMHO, the design with AWS is not comparable to the one with a classical GUI : there is no big added value to separate AWS from the main program. The GUI is allready separated, it's your browser. Lionel Draghi. ^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: Re; [OT] Best way to isolate a GUI? @ 2003-02-18 10:57 Lionel.DRAGHI 2003-02-18 16:29 ` Jano 0 siblings, 1 reply; 62+ messages in thread From: Lionel.DRAGHI @ 2003-02-18 10:57 UTC (permalink / raw) To: comp.lang.ada | -----Message d'origine----- | De: Lionel.DRAGHI@fr.thalesgroup.com ... | IMHO, the design with AWS is not comparable to the one with a | classical GUI | : there is no big added value to separate AWS from the main | program. The GUI | is allready separated, it's your browser. it's _for example_ your browser. ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: Re; [OT] Best way to isolate a GUI? 2003-02-18 10:57 Lionel.DRAGHI @ 2003-02-18 16:29 ` Jano 0 siblings, 0 replies; 62+ messages in thread From: Jano @ 2003-02-18 16:29 UTC (permalink / raw) Lionel.DRAGHI@fr.thalesgroup.com wrote in message news:<mailman.15.1045565811.9948.comp.lang.ada@ada.eu.org>... > | -----Message d'origine----- > | De: Lionel.DRAGHI@fr.thalesgroup.com > ... > | IMHO, the design with AWS is not comparable to the one with a > | classical GUI > | : there is no big added value to separate AWS from the main > | program. The GUI > | is allready separated, it's your browser. > it's _for example_ your browser. Whereas you have a point, I had thought of that. The point of separating AWS from the main program is that 1) It really doesn't perform core functionality 2) I need not to develop a definite implementation of the GUI, web oriented. I have seen the SOAP module in AWS and I like that approach. Is nearly equal to my first idea, only that it's standardized. It leaves open any languaje for the GUI and it's completely isolated. Mmm, anyone using SOAP for similar purposes? ^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: Re; [OT] Best way to isolate a GUI? @ 2003-02-18 18:24 Lionel.DRAGHI 2003-02-18 19:52 ` Jano 0 siblings, 1 reply; 62+ messages in thread From: Lionel.DRAGHI @ 2003-02-18 18:24 UTC (permalink / raw) To: comp.lang.ada | -----Message d'origine----- | De: 402450@cepsz.unizar.es [mailto:402450@cepsz.unizar.es] .. | Whereas you have a point, I had thought of that. The point of | separating AWS from the main program is that | | 1) It really doesn't perform core functionality | 2) I need not to develop a definite implementation of the GUI, web | oriented. That's true, my point is not right. Only the display engine is outside, but the GUI definition is still there... | I have seen the SOAP module in AWS and I like that approach. Is nearly | equal to my first idea, only that it's standardized. It leaves open | any languaje for the GUI and it's completely isolated. Mmm, anyone | using SOAP for similar purposes? I'am not a Distributed System Annex specialist, but the DSA seems to provide a more straightforward way to reach your goal, because there is no need to define a new protocol on top of SOAP or whatever. You just need to define an Ada interface between the GUI and the core, and categorize it the right way (RCI?). It suppose it should then be easy to build separate partition for the core and for the GUI (or a single exe if needed), and to get the core partition able to run independently. Lionel. ^ permalink raw reply [flat|nested] 62+ messages in thread
* RE: Re; [OT] Best way to isolate a GUI? 2003-02-18 18:24 Lionel.DRAGHI @ 2003-02-18 19:52 ` Jano 0 siblings, 0 replies; 62+ messages in thread From: Jano @ 2003-02-18 19:52 UTC (permalink / raw) En el mensaje <mailman.17.1045592634.9948.comp.lang.ada@ada.eu.org>, Lionel.DRAGHI@fr.thalesgroup.com dice... > I'am not a Distributed System Annex specialist, but the DSA seems to provide > a more straightforward way to reach your goal Yes, I'm completely new to the DSA. I'll read about it and will choose between SOAP or DSA. The point I see in favor of SOAP is that doesn't force to use Ada for the GUI. But probably DSA is more flexible with less starting work. I don't know, really... -- ------------------------- Jano 402450[at]cepsz.unizar.es ------------------------- ^ permalink raw reply [flat|nested] 62+ messages in thread
end of thread, other threads:[~2003-02-25 17:57 UTC | newest] Thread overview: 62+ 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 -- strict thread matches above, loose matches on Subject: below -- 2003-02-18 10:26 Re; " Lionel.DRAGHI 2003-02-18 10:57 Lionel.DRAGHI 2003-02-18 16:29 ` Jano 2003-02-18 18:24 Lionel.DRAGHI 2003-02-18 19:52 ` Jano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox