From: Arno P. <ar...@pu...> - 2011-05-05 16:20:06
|
On 5/5/11 6:30 AM, Panayotis Katsaloulis wrote: > > On 05 Μαϊ 2011, at 11:35 π.μ., Markus Heberling wrote: > >> Hi, >> >> I'd like to use a UITableViewDelegate with the C Backend. Some methods >> in that class are optional. XMLVM generates stubs for the, that throw >> the XMLVM_NOT_IMPLEMENTED Error: >> >> JAVA_FLOAT >> org_xmlvm_iphone_UITableViewDelegate_heightForRowAtIndexPath___org_xmlvm_iphone_UITableView_org_xmlvm_iphone_NSIndexPath(JAVA_OBJECT >> me, JAVA_OBJECT n1, JAVA_OBJECT n2) >> { >> //XMLVM_BEGIN_WRAPPER[org_xmlvm_iphone_UITableViewDelegate_heightForRowAtIndexPath___org_xmlvm_iphone_UITableView_org_xmlvm_iphone_NSIndexPath] >> XMLVM_NOT_IMPLEMENTED(); >> //XMLVM_END_WRAPPER >> } >> >> I can override all of the methods, of course, but I rather would leave >> them out. What would be the correct way to handle optional methods? >> >> Markus > > I can't help you with the C backend, but I'll describe a bit what I did > in the same case with the ObjC backend, so that the C Gurus here could > advise the correct answer. > > The problem is, there is no "default" value for these (and all similar) > methods. Moreover, the iOS would behave different, when these methods > are present, and do something else, when these methods are missing. > > What I did on the ObjC backend was to do something similar to what (I > believe) Apple does. > First of all, *all* ObjC delegate methods exist and all point to their > Java counterpart. > Then the method that answers to the ObjC runtime if this method exists > (i.e. respondsToSelector) is overridden. If an actual Java-based > implementation exists, then respondsToSelector responds that the actual > ObjC delegate selector exists (although the ObjC selector *always* > exist). If it doesn't then it replies that this method does not exist. > > WIth such a trick it is possible to properly inform the UITableView that > an optional *Java* method exist, and have the desired/correct behavior. You can do the same with the C backend. The key is to implement respondsToSelector in UITableViewDelegate in such a way that it figures out if a Java method has been overridden or not. This can easily be done with the help of the vtable: if a method is overridden in a derived class, the vtable entry for that method will point to the implementation in the derived class. If the method has not been overridden, the vtable entry will still point to the implementation of the base class. The same trick is used in org_xmlvm_iphone_UIResponder.m (for the C backend) to check if methods such as touchesBegan: have been overridden. Here the relevant code sniplet from that file: VTABLE_PTR func = thiz->tib->vtable[XMLVM_VTABLE_IDX_org_xmlvm_iphone_UIResponder_touchesBegan___java_util_Set_org_xmlvm_iphone_UIEvent]; if (func == (VTABLE_PTR) org_xmlvm_iphone_UIResponder_touchesBegan___java_util_Set_org_xmlvm_iphone_UIEvent) { // vtable index for this method still points to the implementation of // class UIResponder. Delegate event to the next responder [[self nextResponder] touchesBegan:touches withEvent:event]; If the if-condition is true, the method has not been overridden. Hope this helps, Arno |