From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e429176c9adb07b X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-02-17 19:19:31 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!news-han1.dfn.de!news-mue1.dfn.de!newsfeed.stueberl.de!newsr1.ipcore.viaginterkom.de!newsfeed1.eu.ignite.net!news-hub.siol.net!feed.cgocable.net!read2.cgocable.net.POSTED!53ab2750!not-for-mail Message-ID: <3E51A55A.3000101@cogeco.ca> From: "Warren W. Gay VE3WWG" User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: [OT] Best way to isolate a GUI? References: <3E511C15.1040404@acm.org> <3E5121BD.4010200@cogeco.ca> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Date: Mon, 17 Feb 2003 22:15:38 -0500 NNTP-Posting-Host: 24.150.168.167 X-Complaints-To: abuse@cogeco.ca X-Trace: read2.cgocable.net 1045538166 24.150.168.167 (Mon, 17 Feb 2003 22:16:06 EST) NNTP-Posting-Date: Mon, 17 Feb 2003 22:16:06 EST Organization: Cogeco Cable Xref: archiver1.google.com comp.lang.ada:34185 Date: 2003-02-17T22:15:38-05:00 List-Id: 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