func writeAccessorMethods(rt reflect.Type) (accSrc string) { var ( nameCases []string sf reflect.StructField sfType reflect.Type isSid bool sfName string numCase, pos int ) if _, hasSid := rt.FieldByName("HasSid"); !spref(rt.Name(), "ParamOrSid") { accSrc += sfmt("func (me *%s) AccessField(fn string) interface{} {\n\tswitch fn {\n", rt.Name()) for i := 0; i < rt.NumField(); i++ { if sf = rt.Field(i); (len(sf.Name) > 0) && (sf.Name != "Def") && (sf.Name != "Kind") && !sf.Anonymous { if isSid, sfName, sfType = spref(sf.Type.Name(), "Sid"), sf.Name, sf.Type; isSid || (hasSid && (!anyOf(sfType, reflect.Invalid, reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Struct, reflect.UnsafePointer)) && ((sfType.Kind() != reflect.Ptr) || elemType(sfType).Kind() != reflect.Struct)) { if numCase++; isSid { switch sfType.Name() { case "SidBool": sfName += ".B" case "SidString": sfName += ".S" case "SidVec3": sfName += ".Vec3" default: sfName += ".F" } } nameCases = append(nameCases, sf.Name) accSrc += sfmt("\tcase %#v:\n\t\treturn %sme.%s\n", sf.Name, ustr.Ifs(sfType.Kind() == reflect.Ptr, "", "&"), sfName) } else if pos = strings.Index(sfType.String(), "ParamOr"); pos > 0 { // numCase++ switch sfType.String()[pos+len("ParamOr"):] { case "Bool": case "RefSid": case "Float": case "SidFloat": case "Float2": case "Int": } // println(rt.Name() + "." + sf.Name + " => " + sfType.String()) } } } if accSrc += "\t}\n\treturn nil\n}\n\n"; numCase == 0 { accSrc = "" } else { accSrc = sfmt("//\tRefSidFielder implementation.\n//\tSupported field names: \"%v\".\n", strings.Join(nameCases, "\", \"")) + accSrc } } return }
func writeResolverMethods(rt reflect.Type) (outSrc string) { var ( count int walkFields func(reflect.Type, string) ) walkFields = func(tt reflect.Type, pref string) { var ( isPtr bool amper, lnpre string et, ft reflect.Type sf reflect.StructField beginIfNil func() endIfNil func() ) beginIfNil = func() { lnpre = "\t" if isPtr = ft.Kind() == reflect.Ptr; isPtr { outSrc += sfmt("\tif %s != nil {\n", pref+sf.Name) amper = "" lnpre += "\t" } else { amper = "&" } } endIfNil = func() { lnpre = "\t" if isPtr { outSrc += "\t}\n" } } for i := 0; i < tt.NumField(); i++ { if sf = tt.Field(i); sf.Name != "Def" { ft = sf.Type et = elemType(ft) if sf.Anonymous { walkFields(et, pref) } else { if haveSids[et] && !sf.Anonymous { switch ft.Kind() { case reflect.Array, reflect.Map, reflect.Slice: outSrc += sfmt("\tfor _, sidItem := range %s {\n\t\tbag.valRaw, bag.valAsRes, bag.sid = sidItem, %s, sidItem.Sid\n\t\tif val = bag.sidResolve(path); val != nil {\n\t\t\treturn\n\t\t}\n\t}\n", pref+sf.Name, ustr.Ifs(isResolver[et], "sidItem", "nil")) default: beginIfNil() outSrc += sfmt(lnpre+"bag.valRaw, bag.valAsRes, bag.sid = %s, %s, %s.Sid\n"+lnpre+"if val = bag.sidResolve(path); val != nil {\n"+lnpre+"\treturn\n"+lnpre+"}\n", amper+pref+sf.Name, ustr.Ifs(isResolver[et], amper+pref+sf.Name, "nil"), pref+sf.Name) endIfNil() } count++ } else if isResolver[et] { switch ft.Kind() { case reflect.Array, reflect.Map, reflect.Slice: outSrc += sfmt("\tfor _, subItem := range %s {\n\t\tif val = subItem.sidResolve(path, bag); val != nil {\n\t\t\treturn\n\t\t}\n\t}\n", pref+sf.Name) default: beginIfNil() outSrc += sfmt(lnpre+"if val = %s.sidResolve(path, bag); val != nil {\n"+lnpre+"\treturn\n"+lnpre+"}\n", pref+sf.Name) endIfNil() } count++ } else if isInlineStructField(et) { walkFields(et, pref+sf.Name+".") } } } } } rtName := rt.Name() outSrc += sfmt("func (me *%s) sidResolve(path []string, bag *refSidBag) (val interface{}) {\n", rtName) walkFields(rt, "me.") if isResolver[rt] || (count > 0) { typesWritten[rt] = true outSrc += "\treturn\n}\n\n" if _, ok := rt.FieldByName("Id"); ok /*&& (isResolver[rt] || (count > 0))*/ { outSrc += sfmt("func (me *%s) sidResolver(id string) (rsr refSidResolver) {\n\tif (id == me.Id) || (id == \".\") {\n\t\trsr = me\n\t}\n\treturn\n}\n\n", rt.Name()) if strings.HasSuffix(rtName, "Def") && !oneOf(rtName, "PxRigidBodyDef", "PxRigidConstraintDef") { outSrc += sfmt("func (me *Lib%ss) sidResolver(id string) refSidResolver {\n\treturn me.M[id]\n}\n\n", rtName) } } } else { outSrc = "" } return }