RJLRef: $PH/COOL/BDE_LCP_GENCPPnotes080506.txt The Fox alternative to bde's hasType() macro is to check subtype by dynamic casting (see below). This may be of use in current bde/src refactoring. for graphic methods in *ops.cc. It may also be relevant to a more O-O implementation of LCP. So I added notes on gencpp and LCP inter-dependence for auto-generation of dynamic behavioral and/or event-driven control flow tables for LCP. I hope this makes sense to you Robert. I am confused by it myself, and I need a consultant to shed theoretical light on it. It makes some sense to me but I am not completely satisfied that it is any better at code generation/table interpretation than proprietary methods. Trouble is - I can't see inside the latter. Four newer books by Wierenga, BPDouglas, Samek, and Drusinsky go into state modeling in much more detail but don't come much closer in my opinion to shedding light on LCP than did Shlaer-Mellor's Object Life Cycles and Kennedy-Carter's text. Harel's State Chart papers are more theoretical and less OO-based. -RJL 080506 Bde's display List of drawable objects is hand-coded because its classes node, caption, hlink, text were never made part of bde's data model so it does not make use of chgen or gencpp for code generation as it might. Event types (ET and EI) are also part of LCP's State Model (SM)) but not yet in bde's schema. ET and EI are also needed for bdeState and/or LCP use. [Note that saving a diagram FILE does not require auto-saving any display lists, although it could. We could make the saved tables a sub-view of the schema, and convert a diagram to display coords only on demand. Saving display lists would duplicate info that is already in HN, CG, HL and {HA|HI|GX}; it merely avoids 'on-demand' recalculating int display coords from float 'World' coords which is very fast.] Jerouen says fox dynamic dispatch 'only requires that the object have a vtable'. However, does having a vtable mean having support for method inheritance and overrides? Wickipedia says: "A virtual method table, virtual function table, dispatch table, or vtable, is a mechanism used in programming language implementations in order to support dynamic polymorphism, i.e., run-time method binding." BDE/pr_util uses structs. Does dynamic casting require using gencpp to support bde instead of chgen? or just using g++ not gcc? I'm afraid we deferred that question by using delegation and composition not real inheritance in chgen code generation. Upward compatibility from chgen over-constrained gencpp to do the same (so far). E.g. for LCP interpretation a generic class AC and its child-AI's has static data in the AC (a child-set of State Models (SM) for its methods in tables ST, TR, ET, EN). An AC also has a child-set of AI's; each AI saves an object's current state in its AI state data field. Class AC has application-specific subclasses like OP, BA, JT etc. in the JuicePlant JPsim, likewise in the Hominid project which is implemented with LCP. [Note that AC does not have diamond-shaped subclassing into AI and SM; it has 2-way decomposition into radically different[?] component types. Each AC also has a subclass which is an application-specific class. That sucbclass inherits its static control-flow behavior from its AC and its dynamic instance state from its corresponding AI instance.] The challenge in upgrading gencpp to auto-generate real inheritable method declarations [and vtables?] for state models is to decide whether AC--->AI is a single abstract class AC whose AC-object instances contain shared static data member names but different instance values, plus multiple AI's per AC object, holding instance-specific data member value fields. [Each AC refers to a distinct family of SM's, and its AI-children represent multiple instances of the same application object class. Each of these objectgs has its own individual control state and event que source and destination object references.] LCP's function table lookup may be redundant, if it is equivalent to a vtable, but how can we convert this LCP function table, with class method definitions that are table-driven at link time, into vtable content that g++ (I presume) binds to subclasses at compile time?? Does this mean that gencpp auto-generates class definitions that declare action routine class methods and thereby binds them to LCP's event dispatcher? (State actions are private code fragments gleaned from state and guarded event switch cases inside callback functions from the GUI that can become public class methods like node_resize.} The instance-level control state is in the AI itself and the action subroutine index field is in table ST of the state model SM referenced from the superclass instance AC. The actual method address bound to the routine index and its functionname at link-time is defined as (functionname*) and generated byu ajlopez's Hominid upgrade. This name is in table ST. It can be extracted from the application subclass state diagram by bde2SM conversion to table ST or by direct definition of table ST for that SM. Stroustrup says that by definition "a struct is a class in which members are by default public". [in "C++ Programming Language" 3rd Ed. 1997 10.2.8 p. 234] He gives an example struct and class having same data and methods (except for access). (He does not mention inheritance or subclassing for structs. In fact, 5.7 Structures p.104 only says "A struct is a simple form of a class." Nor does that book's index mention 'vtable'.) He uses struct for a class with all data public and says struct constructors and access functions are useful shorthand but do not guarantee properties of the type. Forwarded message: > From lechner@cs.uml.edu Wed Sep 20 18:18:13 2006 > From: Bob Lechner > Message-Id: <200609202220.k8KMKSl2206590@saturn.cs.uml.edu> > Subject: Fox alt to bde hasType to Check type of a widget (dynamic cast in fox) > > This may be useful on a bde graphobject display (List) class item, > to see if it is in the graph, node, caption or hlink subclass. > > Right now bde/src uses macro hasType(id,XX) below. > (267 calls or comments, including assert(hasType(...) checks.) > This is analogous to fox's isMemberOf(...) below. > > hasType is application-independent, like dprint: > ------ > mercury(16)> grep '#define hasType' ../pr_util_nolog/9*.h > 792:#define hasType(key, ttabbr) \ > ((&key)?(strstr(decode_retstr(&key),#ttabbr)?1:0):0) > -------- > decode_retstr looks up a ttabbr at an index and does a string compare. > But (&key)==encode(ttabbr) is slower since encode serialy > searches for ttabbr in a list of string values. > > > The polymorphic list at topobject->subobjects[->next...] > was never dis-aggregated into subtype lists. > The pr_loaded VMNetDB segregates types in bde's component hierarchy. > This is more faithful to bde's [relational] data model. > > R Lechner > > Forwarded message: > >> > From foxgui-users-bounces@lists.sourceforge.net Tue Sep 19 22:16:47 2006 >> > To: foxgui-users@lists.sourceforge.net >> > Cc: The Devils Jester >> > Subject: Re: [Foxgui-users] Check what type a widget is? >> > >> > On Tuesday 19 September 2006 19:57, The Devils Jester wrote: >> > > What is the proper method of checking to see what class a specific widget= >> > is? >> > > (I.E. I need to determine if its a button or a toggle button, etc...) >> > >> > >> > Even so, for general reference: >> > >> > if(window->isMemberOf(FXMETACLASS(ClassName))){ >> > ... >> > } >> > >> > This would work; however, the C++ way is better: >> > >> > ClassName *someclass=dynamic_cast(window); >> > if(someclass){ >> > ... >> > } >> > >> > >> > This is language-supported, and since you usually want to know >> > what class something is in order to cast the pointer, it kills >> > two birds with one stone, so to speak. >> > >> > Apart from that, a C++ style cast takes care of potential multiple- >> > inheritance issues [not that this is relevant inside FOX itself, >> > which is strictly single-inheritance; however it may be an issue >> > in your own classes]. >> > >> > - Jeroen >> > > Message 3/1369 From Jeroen van der Zijp Sep 20, 06 08:17:46 PM -0500 > Cc: The Devils Jester > Subject: Re: [Foxgui-users] Check what type a widget is? > On Wednesday 20 September 2006 17:23, The Devils Jester wrote: > > So in the C++ example you gave, ClassName would be say FXLabel, and > > if the passed object 'window' has FXLabel in its inheritance history, > > the new pointer 'someclass' will be a non null value? Sorry I am a > > bit green as far as OOP goes. > > C++ has added dynamic_cast<> as a checked downcast specifically for these > situations. It only requires that the object have a vtable [which FXObject > and its derivatives do]. > > The other one is static_cast<>, which you can deploy if you KNOW that > the cast will be successful [it doesn't check, like dynamic_cast does, > thus its faster]. > > A C++ object which inherits from more than one base class comprises > all of its base classes in its struct. When you "cut" it down to > one of its bases, the C++ compiler knows the type and can add the > necessary struct-offsets. > > However, when you down-cast, with the C-style cast you'd just be > reinterpreting the pointer to this as a pointer to that, and thus > in case of multiple inheritance this will be total garbage. > > So its *highly* recommended to use the new C++ style casts when navigating > a class hierarchy, and when the class-hierarchy uses M.I. it is *essential*. > > Regards, > > - Jeroen