Skip to content

Commit 9e68508

Browse files
authored
Merge pull request #3714 from ikemen-engine/fix7
fix: warning inheritance behaviour
2 parents 5b26efa + bc75724 commit 9e68508

2 files changed

Lines changed: 59 additions & 23 deletions

File tree

src/iniutils.go

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,15 +1969,6 @@ func SetAnim(obj interface{}, fVal, structVal, parent reflect.Value, sffOverride
19691969
anim = int32(fv.Int())
19701970
}
19711971
if fv, ok := get("Spr"); ok && fv.Kind() == reflect.Array && fv.Len() == 2 {
1972-
if warnMissing {
1973-
if _, sf, ok := findFieldByINITag(structVal, "spr"); ok &&
1974-
strings.EqualFold(strings.TrimSpace(sf.Tag.Get("warn")), "false") {
1975-
warnMissing = false
1976-
} else if _, sf, ok := findFieldByINITag(parent, "spr"); ok &&
1977-
strings.EqualFold(strings.TrimSpace(sf.Tag.Get("warn")), "false") {
1978-
warnMissing = false
1979-
}
1980-
}
19811972
spr[0] = int32(fv.Index(0).Int())
19821973
spr[1] = int32(fv.Index(1).Int())
19831974
hasSpr = true
@@ -2610,9 +2601,13 @@ func PopulateDataPointers(obj interface{}, rootLocalcoord [2]int32) {
26102601
rootSff = s
26112602
}
26122603
}
2604+
var inheritedKeys map[string]bool
2605+
if m, ok := obj.(*Motif); ok {
2606+
inheritedKeys = m.inheritedKeys
2607+
}
26132608

26142609
// Thread both localcoord and effective SFF through recursion.
2615-
var populate func(v reflect.Value, parent reflect.Value, currentLocalCoord [2]int32, currentSff *Sff, skipInit bool, warnMissing bool)
2610+
var populate func(v reflect.Value, parent reflect.Value, currentLocalCoord [2]int32, currentSff *Sff, skipInit bool, warnMissing bool, path string)
26162611

26172612
// Types we look for
26182613
animPtrType := reflect.TypeOf((*Anim)(nil))
@@ -2622,15 +2617,15 @@ func PopulateDataPointers(obj interface{}, rootLocalcoord [2]int32) {
26222617
fadePtrType := reflect.TypeOf((*Fade)(nil))
26232618

26242619
// The recursive function
2625-
populate = func(v reflect.Value, parent reflect.Value, currentLocalCoord [2]int32, currentSff *Sff, skipInit bool, warnMissing bool) {
2620+
populate = func(v reflect.Value, parent reflect.Value, currentLocalCoord [2]int32, currentSff *Sff, skipInit bool, warnMissing bool, path string) {
26262621
if !v.IsValid() {
26272622
return
26282623
}
26292624
if v.Kind() == reflect.Ptr {
26302625
if v.IsNil() {
26312626
return
26322627
}
2633-
populate(v.Elem(), parent, currentLocalCoord, currentSff, skipInit, warnMissing)
2628+
populate(v.Elem(), parent, currentLocalCoord, currentSff, skipInit, warnMissing, path)
26342629
return
26352630
}
26362631

@@ -2643,6 +2638,17 @@ func PopulateDataPointers(obj interface{}, rootLocalcoord [2]int32) {
26432638
// Effective SFF for this struct (may be overridden by the field tag of children)
26442639
effectiveSffForThisStruct := currentSff
26452640

2641+
joinPath := func(base, elem string) string {
2642+
elem = strings.ToLower(strings.ReplaceAll(strings.TrimSpace(elem), " ", "_"))
2643+
if elem == "" {
2644+
return base
2645+
}
2646+
if base == "" {
2647+
return elem
2648+
}
2649+
return base + "." + elem
2650+
}
2651+
26462652
for i := 0; i < v.NumField(); i++ {
26472653
fVal := v.Field(i)
26482654
fType := t.Field(i)
@@ -2672,27 +2678,33 @@ func PopulateDataPointers(obj interface{}, rootLocalcoord [2]int32) {
26722678
}
26732679
}
26742680

2681+
fieldPath := path
2682+
if tag := strings.TrimSpace(fType.Tag.Get("ini")); tag != "" &&
2683+
!strings.HasPrefix(strings.ToLower(tag), "map:") {
2684+
fieldPath = joinPath(path, tag)
2685+
}
2686+
26752687
// Check for skipInit tag on this field
26762688
childSkipInit := skipInit
26772689
if fType.Tag.Get("skipinit") == "true" {
26782690
childSkipInit = true
26792691
}
26802692
childWarnMissing := warnMissing
2681-
if strings.EqualFold(strings.TrimSpace(fType.Tag.Get("warn")), "false") {
2693+
if inheritedKeys != nil && fieldPath != "" && (inheritedKeys[fieldPath+".anim"] || inheritedKeys[fieldPath+".spr"]) {
26822694
childWarnMissing = false
26832695
}
26842696

26852697
kind := fVal.Kind()
26862698

26872699
// Recurse for struct or non-nil ptr
26882700
if kind == reflect.Struct || (kind == reflect.Ptr && !fVal.IsNil()) {
2689-
populate(fVal, v, localCoordForThisStruct, nextSff, childSkipInit, childWarnMissing)
2701+
populate(fVal, v, localCoordForThisStruct, nextSff, childSkipInit, childWarnMissing, fieldPath)
26902702
continue
26912703
}
26922704
// If it's a map, recurse as well
26932705
if kind == reflect.Map {
26942706
// Pass along the possibly overridden SFF from this field's tag.
2695-
populate(fVal, parent, localCoordForThisStruct, nextSff, childSkipInit, childWarnMissing)
2707+
populate(fVal, parent, localCoordForThisStruct, nextSff, childSkipInit, childWarnMissing, fieldPath)
26962708
continue
26972709
}
26982710
// If it's *Anim
@@ -2743,12 +2755,19 @@ func PopulateDataPointers(obj interface{}, rootLocalcoord [2]int32) {
27432755
// If we have a slice or array, recurse into each element
27442756
case reflect.Slice, reflect.Array:
27452757
for i := 0; i < v.Len(); i++ {
2746-
populate(v.Index(i), parent, currentLocalCoord, currentSff, skipInit, warnMissing)
2758+
populate(v.Index(i), parent, currentLocalCoord, currentSff, skipInit, warnMissing, path)
27472759
}
27482760
case reflect.Map:
27492761
for _, key := range v.MapKeys() {
27502762
val := v.MapIndex(key)
2751-
populate(val, parent, currentLocalCoord, currentSff, skipInit, warnMissing)
2763+
childPath := path
2764+
if key.Kind() == reflect.String {
2765+
k := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(key.String()), " ", "_"))
2766+
if k != "" {
2767+
childPath = k
2768+
}
2769+
}
2770+
populate(val, parent, currentLocalCoord, currentSff, skipInit, warnMissing, childPath)
27522771
}
27532772
default:
27542773
// basic types: do nothing
@@ -2761,7 +2780,7 @@ func PopulateDataPointers(obj interface{}, rootLocalcoord [2]int32) {
27612780
return
27622781
}
27632782
// Start recursion with the original user-supplied localcoord
2764-
populate(v.Elem(), v.Elem(), rootLocalcoord, rootSff, false, true)
2783+
populate(v.Elem(), v.Elem(), rootLocalcoord, rootSff, false, true, "")
27652784
}
27662785

27672786
// Split a [Music] key into (prefix, property) while allowing dots in prefix.

src/motif.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ type FaceProperties struct {
415415
AnimationCharPreloadProperties `skipinit:"true"`
416416
Key []string `ini:"key"` // only used by [VS Screen]
417417
} `ini:"done"`
418-
Random AnimationProperties `ini:"random"` // only used by [Select Info]
419-
Loading AnimationProperties `ini:"loading" warn:"false"` // only used by [Select Info] and [VS Screen]
418+
Random AnimationProperties `ini:"random"` // only used by [Select Info]
419+
Loading AnimationProperties `ini:"loading"` // only used by [Select Info] and [VS Screen]
420420
Velocity [2]float32 `ini:"velocity"`
421421
MaxDist [2]float32 `ini:"maxdist"`
422422
Accel [2]float32 `ini:"accel"`
@@ -736,7 +736,7 @@ type SelectInfoProperties struct {
736736
AnimationStagePreloadProperties `skipinit:"true"`
737737
Bg AnimationProperties `ini:"bg"`
738738
Random AnimationProperties `ini:"random"`
739-
Loading AnimationProperties `ini:"loading" warn:"false"`
739+
Loading AnimationProperties `ini:"loading"`
740740
} `ini:"portrait"`
741741
} `ini:"stage"`
742742
Done struct {
@@ -748,7 +748,7 @@ type SelectInfoProperties struct {
748748
} `ini:"cancel"`
749749
Portrait struct {
750750
AnimationCharPreloadProperties `skipinit:"true"`
751-
Loading AnimationProperties `ini:"loading" warn:"false"`
751+
Loading AnimationProperties `ini:"loading"`
752752
} `ini:"portrait"`
753753
Title TextMapProperties `ini:"title"`
754754
Record TextMapProperties `ini:"record"`
@@ -795,7 +795,7 @@ type VsScreenProperties struct {
795795
Portrait struct {
796796
AnimationStagePreloadProperties `skipinit:"true"`
797797
Bg AnimationProperties `ini:"bg"`
798-
Loading AnimationProperties `ini:"loading" warn:"false"`
798+
Loading AnimationProperties `ini:"loading"`
799799
} `ini:"portrait"`
800800
Snd [2]int32 `ini:"snd" default:"-1,0"`
801801
} `ini:"stage"`
@@ -1342,6 +1342,7 @@ type Motif struct {
13421342
WarningInfo WarningInfoProperties `ini:"warning_info"`
13431343
Glyphs map[string]*GlyphProperties `ini:"glyphs" literal:"true" insensitivekeys:"false" sff:"GlyphsSff"`
13441344
fntIndexByKey map[string]int // filepath|height -> index
1345+
inheritedKeys map[string]bool // normalized .anim/.spr paths assigned by overrideParams inheritance
13451346
ch MotifChallenger
13461347
co MotifContinue
13471348
de MotifDemo
@@ -2008,6 +2009,9 @@ func (m *Motif) mergeWithInheritance(specs []InheritSpec) {
20082009
if m == nil || m.IniFile == nil {
20092010
return
20102011
}
2012+
if m.inheritedKeys == nil {
2013+
m.inheritedKeys = make(map[string]bool)
2014+
}
20112015
user := m.UserIniFile
20122016
defs := m.DefaultOnlyIni
20132017
merged := m.IniFile
@@ -2154,6 +2158,18 @@ func (m *Motif) mergeWithInheritance(specs []InheritSpec) {
21542158
//fmt.Printf("Warning: inheritance set failed for %s = %q: %v\n", query, val, err)
21552159
}
21562160

2161+
// Remember only anim/spr values that were actually inherited into the destination.
2162+
// Direct destination values from system.def must keep warning on missing sprites.
2163+
switch strings.ToLower(suf) {
2164+
case "anim", "spr":
2165+
switch src {
2166+
case srcUserSrc, srcDefSrc:
2167+
m.inheritedKeys[query] = true
2168+
default:
2169+
delete(m.inheritedKeys, query)
2170+
}
2171+
}
2172+
21572173
// If a value comes from the user INI (directly or via src), copy it into m.UserIniFile
21582174
// so fixLocalcoordOverrides treats the element as user-touched, including inherited keys.
21592175
if user != nil {
@@ -2345,6 +2361,7 @@ func (m *Motif) initStruct() {
23452361
m.fadeOut = newFade()
23462362
m.fadePolicy = FadeContinue
23472363
m.fntIndexByKey = make(map[string]int)
2364+
m.inheritedKeys = make(map[string]bool)
23482365
}
23492366

23502367
func (m *Motif) loadBgDefProperties(bgDef *BgDefProperties, bgname, spr string) {

0 commit comments

Comments
 (0)