[Gambas-devel] Multi-level virtual objects, inheritance and symbol resolution mess

Tobias Boege taboege at ...176...
Sat Sep 6 17:05:07 CEST 2014


On Sat, 06 Sep 2014, Beno?t Minisini wrote:
> Le 05/09/2014 21:26, Tobias Boege a ?crit :
> > Hi Benoit,
> >
> > I'm almost done with implementing an adjacency matrix based Graph class
> > (GraphMatrix), to then set the Graph interface in stone. See #6451 for
> > the code I'll talk about.
> >
> > Only there is one obstacle to overcome: accessing symbols of a
> > GraphMatrix.Vertices[sVertex] object. The situation is as follows:
> >
> >    - GraphMatrix Inherits Graph (which is an "abstract" class).
> >    - .Vertices is a virtual object whose _get method calls back:
> >    - Me._getVertex (which is within GraphMatrix and) which returns a:
> >    - _Graph_Vertex, a virtual class which is the base of all implementation-
> >      specific vertex classes.
> >    - In case of GraphMatrix, this is a _Matrix_Vertex virtual class which
> >      Inherits _Graph_Vertex.
> >
> >>From there I want to access the InDegree property which is properly
> > implemented in the _Matrix_Vertex class but all I get is ("a" is an existing
> > vertex in the graph):
> >
> >    hGraph.Vertices["a"].InDegree
> >    >> (Function GraphMatrix:3)
> >
> > Indeed, InDegree is the 3rd symbol in _Matrix_Vertex. If I issue
> >
> >    hGraph.Vertices["a"].InDegree()
> >    >> Error: Not enough arguments
> >
> > The 3rd symbol in GraphMatrix is _getEdge which needs two arguments... If I
> > try that:
> >
> >    hGraph.Vertices["a"].InDegree("b", "a")
> >    >> Error: Edge does not exist
> >
> > which is the error I would expect from my graph if I called the _getEdge
> > method! It seems like the InDegree property is not mapped to my
> > _Matrix_Vertex.InDegree implementation but to the method of same index in
> > GraphMatrix.
> >
> > _Matrix_Vertex actually is a virtual class obtained via a virtual class
> > interface from GraphMatrix. Is the virtual class information lost somewhere
> > on the way or do I exceed a limit here?
> >
> > ---
> >
> > So, in a nutshell: GraphMatrix.Vertices is a virtual class which calls back
> > GraphMatrix._getVertex which returns another virtual object from which I
> > want to access a property.
> >
> > In a graph class (ImageGraph) implemented in Gambas -- where there are no
> > virtual classes -- the _ImageGraph_Vertex Inherits _Graph_Vertex is a real
> > class. And there it works!
> >
> > Attached are: the project which uses the native GraphMatrix class and fails,
> > and the working ImageGraph Gambas class. I would really like to finish this
> > thing soon. If you could take a good look, that would surely be a great help.
> >
> > Regards,
> > Tobi
> >
> 
> I'm currently looking at it...
> 
> But why didn't you do as I told you, i.e. use an internal dispatch 
> interface (a structure of function pointers) like I did for the Paint 
> class?
> 

Ah right. I knew there was something... I just picked this up after a long
pause. I'm on it now.

> Otherwise things are so slow. Calling GB.GetFunction() implies a symbol 
> table lookup and signature verification at each call!
> 
> I suggest:
> 
> - Creating a struct of function pointers that represents the graph node 
> interface.
> 
> - Adding a pointer on that struct in each graph.
> 
> - Use it everywhere you need.
> 
> - All classes written in C/C++ inheriting Graph must implement that 
> struct of function pointers and put a pointer on it in its objects.
> 
> - For classes written in Gambas inheriting Graph, you must create a 
> struct of function pointers that calls the Gambas functions you defined 
> ('_getVertex', '_getEdge', ...). Calls to GB.GetFunction() should be 
> done once and cached, the first time you instanciate an object of that 
> class.
> 

So, I would keep a structure of GB_FUNCTIONs? Can I keep this struct once
for each class and substitute GB_FUNCTION.object for each call or is this
not supported (depends on what is in GB_FUNCTION.desc)?

> That way, performance should be acceptable. :-)
> 
> By the way: you should use GB_DECLARE_VIRTUAL() instead of GB_DECLARE() 
> for declaring virtual classes. No need to use GB_VIRTUAL_CLASS() then. 
> And virtual classes name should begin with a dot, not an underscore. I'm 
> not sure at the moment it has no impact in the interpreter...
> 

I wanted to adhere to this rule but the problem is/was that _Graph_Vertex
was virtual and Gambas classes needed to inherit it but IIRC you cannot
inherit classes beginning with a dot in Gambas (syntactically).

Regards,
Tobi

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk




More information about the Devel mailing list