@@ -414,6 +414,23 @@ def get_whole_name(self, generator):
414414
415415 return name
416416
417+ def object_can_convert (self , generator , is_to_native = True ):
418+ if self .is_object :
419+ keys = []
420+ if self .canonical_type != None :
421+ keys .append (self .canonical_type .name )
422+ keys .append (self .name )
423+ if is_to_native :
424+ to_native_dict = generator .config ['conversions' ]['to_native' ]
425+ if NativeType .dict_has_key_re (to_native_dict , keys ):
426+ return True
427+ else :
428+ from_native_dict = generator .config ['conversions' ]['from_native' ]
429+ if NativeType .dict_has_key_re (from_native_dict , keys ):
430+ return True
431+
432+ return False
433+
417434 def __str__ (self ):
418435 return self .canonical_type .whole_name if None != self .canonical_type else self .whole_name
419436
@@ -426,11 +443,34 @@ def __init__(self, cursor):
426443 self .location = cursor .location
427444 member_field_re = re .compile ('m_(\w+)' )
428445 match = member_field_re .match (self .name )
446+ self .signature_name = self .name
447+ self .ntype = NativeType .from_type (cursor .type )
429448 if match :
430449 self .pretty_name = match .group (1 )
431450 else :
432451 self .pretty_name = self .name
433452
453+ @staticmethod
454+ def can_parse (ntype ):
455+ if ntype .kind == cindex .TypeKind .POINTER :
456+ return False
457+ native_type = NativeType .from_type (ntype )
458+ if ntype .kind == cindex .TypeKind .UNEXPOSED and native_type .name != "std::string" :
459+ return False
460+ return True
461+
462+ def generate_code (self , current_class = None , generator = None ):
463+ gen = current_class .generator if current_class else generator
464+ config = gen .config
465+
466+ if config ['definitions' ].has_key ('public_field' ):
467+ tpl = Template (config ['definitions' ]['public_field' ],
468+ searchList = [current_class , self ])
469+ self .signature_name = str (tpl )
470+ tpl = Template (file = os .path .join (gen .target , "templates" , "public_field.c" ),
471+ searchList = [current_class , self ])
472+ gen .impl_file .write (str (tpl ))
473+
434474# return True if found default argument.
435475def iterate_param_node (param_node , depth = 1 ):
436476 for node in param_node .get_children ():
@@ -674,6 +714,7 @@ def __init__(self, cursor, generator):
674714 self .namespaced_class_name = self .class_name
675715 self .parents = []
676716 self .fields = []
717+ self .public_fields = []
677718 self .methods = {}
678719 self .static_methods = {}
679720 self .generator = generator
@@ -778,6 +819,9 @@ def generate_code(self):
778819 if self .generator .script_type == "lua" :
779820 for m in self .override_methods_clean ():
780821 m ['impl' ].generate_code (self , is_override = True )
822+ for m in self .public_fields :
823+ if self .generator .should_bind_field (self .class_name , m .name ):
824+ m .generate_code (self )
781825 # generate register section
782826 register = Template (file = os .path .join (self .generator .target , "templates" , "register.c" ),
783827 searchList = [{"current_class" : self }])
@@ -850,6 +894,8 @@ def _process_node(self, cursor):
850894
851895 elif cursor .kind == cindex .CursorKind .FIELD_DECL :
852896 self .fields .append (NativeField (cursor ))
897+ if self ._current_visibility == cindex .AccessSpecifierKind .PUBLIC and NativeField .can_parse (cursor .type ):
898+ self .public_fields .append (NativeField (cursor ))
853899 elif cursor .kind == cindex .CursorKind .CXX_ACCESS_SPEC_DECL :
854900 self ._current_visibility = cursor .get_access_specifier ()
855901 elif cursor .kind == cindex .CursorKind .CXX_METHOD and cursor .get_availability () != cindex .AvailabilityKind .DEPRECATED :
@@ -936,6 +982,7 @@ def __init__(self, opts):
936982 self .impl_file = None
937983 self .head_file = None
938984 self .skip_classes = {}
985+ self .bind_fields = {}
939986 self .generated_classes = {}
940987 self .rename_functions = {}
941988 self .rename_classes = {}
@@ -973,6 +1020,16 @@ def __init__(self, opts):
9731020 self .skip_classes [class_name ] = match .group (1 ).split (" " )
9741021 else :
9751022 raise Exception ("invalid list of skip methods" )
1023+ if opts ['field' ]:
1024+ list_of_fields = re .split (",\n ?" , opts ['field' ])
1025+ for field in list_of_fields :
1026+ class_name , fields = field .split ("::" )
1027+ self .bind_fields [class_name ] = []
1028+ match = re .match ("\[([^]]+)\]" , fields )
1029+ if match :
1030+ self .bind_fields [class_name ] = match .group (1 ).split (" " )
1031+ else :
1032+ raise Exception ("invalid list of bind fields" )
9761033 if opts ['rename_functions' ]:
9771034 list_of_function_renames = re .split (",\n ?" , opts ['rename_functions' ])
9781035 for rename in list_of_function_renames :
@@ -1031,6 +1088,28 @@ def should_skip(self, class_name, method_name, verbose=False):
10311088 print "%s will be accepted (%s, %s)" % (class_name , key , self .skip_classes [key ])
10321089 return False
10331090
1091+ def should_bind_field (self , class_name , field_name , verbose = False ):
1092+ if class_name == "*" and self .bind_fields .has_key ("*" ):
1093+ for func in self .bind_fields ["*" ]:
1094+ if re .match (func , method_name ):
1095+ return True
1096+ else :
1097+ for key in self .bind_fields .iterkeys ():
1098+ if key == "*" or re .match ("^" + key + "$" , class_name ):
1099+ if verbose :
1100+ print "%s in bind_fields" % (class_name )
1101+ if len (self .bind_fields [key ]) == 1 and self .bind_fields [key ][0 ] == "*" :
1102+ if verbose :
1103+ print "All public fields of %s will be bound" % (class_name )
1104+ return True
1105+ if field_name != None :
1106+ for field in self .bind_fields [key ]:
1107+ if re .match (field , field_name ):
1108+ if verbose :
1109+ print "Field %s of %s will be bound" % (field_name , class_name )
1110+ return True
1111+ return False
1112+
10341113 def in_listed_classes (self , class_name ):
10351114 """
10361115 returns True if the class is in the list of required classes and it's not in the skip list
@@ -1124,6 +1203,7 @@ def generate_code(self):
11241203 self .head_file .close ()
11251204 self .doc_file .close ()
11261205
1206+
11271207 def _pretty_print (self , diagnostics ):
11281208 print ("====\n Errors in parsing headers:" )
11291209 severities = ['Ignored' , 'Note' , 'Warning' , 'Error' , 'Fatal' ]
@@ -1426,6 +1506,7 @@ def main():
14261506 'base_classes_to_skip' : config .get (s , 'base_classes_to_skip' ),
14271507 'abstract_classes' : config .get (s , 'abstract_classes' ),
14281508 'skip' : config .get (s , 'skip' ),
1509+ 'field' : config .get (s , 'field' ) if config .has_option (s , 'field' ) else None ,
14291510 'rename_functions' : config .get (s , 'rename_functions' ),
14301511 'rename_classes' : config .get (s , 'rename_classes' ),
14311512 'out_file' : opts .out_file or config .get (s , 'prefix' ),
0 commit comments