custom decoder

This commit is contained in:
Robert Janetzko 2022-04-11 20:30:43 +00:00
parent ef5c2ca337
commit ed3cb294c9
6 changed files with 441 additions and 91 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
region*.xml *legends.xml
*legends_plus.xml
legendsbrowser legendsbrowser
*.pprof *.pprof
*.png *.png

35
main.go
View File

@ -9,26 +9,40 @@ import (
"runtime" "runtime"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pkg/profile"
) )
var world model.World var world model.World
func main() { func main() {
defer profile.Start(profile.MemProfile).Stop() // defer profile.Start(profile.MemProfile).Stop()
go func() { // go func() {
http.ListenAndServe(":8081", nil) // http.ListenAndServe(":8081", nil)
}() // }()
fmt.Println("Hallo Welt!") fmt.Println("Hallo Welt!")
// world.Load("region1-00152-01-01-legends.xml") // world.Load("region1-00152-01-01-legends_plus.xml")
world.Load("region2-00195-01-01-legends.xml") world.Load("region2-00195-01-01-legends.xml")
// world.Load("Agora-00033-01-01-legends_plus.xml")
runtime.GC() runtime.GC()
world.Process() world.Process()
model.ListOtherElements(&world.HistoricalEvents) // model.ListOtherElements("world", &[]*model.World{&world})
// listOtherElements(&world.HistoricalFigures) // model.ListOtherElements("region", &world.Regions)
// model.ListOtherElements("underground regions", &world.UndergroundRegions)
// model.ListOtherElements("landmasses", &world.Landmasses)
// model.ListOtherElements("sites", &world.Sites)
// model.ListOtherElements("world constructions", &world.WorldConstructions)
// model.ListOtherElements("artifacts", &world.Artifacts)
// model.ListOtherElements("entities", &world.Entities)
// model.ListOtherElements("hf", &world.HistoricalFigures)
// model.ListOtherElements("events", &world.HistoricalEvents)
// model.ListOtherElements("collections", &world.HistoricalEventCollections)
// model.ListOtherElements("era", &world.HistoricalEras)
// model.ListOtherElements("danceForm", &world.DanceForms)
// model.ListOtherElements("musicalForm", &world.MusicalForms)
// model.ListOtherElements("poeticForm", &world.PoeticForms)
// model.ListOtherElements("written", &world.WrittenContents)
router := mux.NewRouter().StrictSlash(true) router := mux.NewRouter().StrictSlash(true)
@ -42,6 +56,11 @@ func main() {
server.RegisterResource(router, "collection", world.HistoricalEventCollectionMap) server.RegisterResource(router, "collection", world.HistoricalEventCollectionMap)
server.RegisterResource(router, "entity", world.EntityMap) server.RegisterResource(router, "entity", world.EntityMap)
server.RegisterResource(router, "event", world.HistoricalEventMap) server.RegisterResource(router, "event", world.HistoricalEventMap)
server.RegisterResource(router, "era", world.HistoricalEraMap)
server.RegisterResource(router, "danceForm", world.DanceFormMap)
server.RegisterResource(router, "musicalForm", world.MusicalFormMap)
server.RegisterResource(router, "poeticForm", world.PoeticFormMap)
server.RegisterResource(router, "written", world.WrittenContentMap)
spa := server.SpaHandler{StaticPath: "frontend/dist/legendsbrowser", IndexPath: "index.html"} spa := server.SpaHandler{StaticPath: "frontend/dist/legendsbrowser", IndexPath: "index.html"}
router.PathPrefix("/").Handler(spa) router.PathPrefix("/").Handler(spa)

View File

@ -10,7 +10,10 @@ import (
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
) )
func ListOtherElements[T TypedOthers](items *[]T) { func ListOtherElements[T Others](name string, items *[]T) {
fmt.Println()
fmt.Println(name)
fmt.Println()
m := make(map[string]map[string]bool) m := make(map[string]map[string]bool)
cantInt := make(map[string]bool) cantInt := make(map[string]bool)
isObj := make(map[string]bool) isObj := make(map[string]bool)
@ -18,11 +21,12 @@ func ListOtherElements[T TypedOthers](items *[]T) {
for _, item := range *items { for _, item := range *items {
found := make(map[string]bool) found := make(map[string]bool)
for _, el := range item.Others() { for _, el := range item.Others() {
if !m[el.XMLName.Local][item.Type()] { t := name // item.Type()
if !m[el.XMLName.Local][t] {
if m[el.XMLName.Local] == nil { if m[el.XMLName.Local] == nil {
m[el.XMLName.Local] = map[string]bool{} m[el.XMLName.Local] = map[string]bool{}
} }
m[el.XMLName.Local][item.Type()] = true m[el.XMLName.Local][t] = true
} }
_, err := strconv.Atoi(el.Value) _, err := strconv.Atoi(el.Value)
if err != nil { if err != nil {

View File

@ -6,17 +6,24 @@ type Region struct {
XMLName xml.Name `xml:"region" json:"-"` XMLName xml.Name `xml:"region" json:"-"`
NamedObject NamedObject
Type string `xml:"type" json:"type"` Type string `xml:"type" json:"type"`
OtherElements
EventObject
} }
type UndergroundRegion struct { type UndergroundRegion struct {
XMLName xml.Name `xml:"underground_region" json:"-"` XMLName xml.Name `xml:"underground_region" json:"-"`
NamedObject NamedObject
Type string `xml:"type" json:"type"` Type string `xml:"type" json:"type"`
Depth *int `xml:"depth" json:"depth,omitempty"`
OtherElements
EventObject
} }
type Landmass struct { type Landmass struct {
XMLName xml.Name `xml:"landmass" json:"-"` XMLName xml.Name `xml:"landmass" json:"-"`
NamedObject NamedObject
OtherElements
EventObject
} }
type Site struct { type Site struct {
@ -27,6 +34,7 @@ type Site struct {
Rectangle string `xml:"rectangle" json:"rectangle"` Rectangle string `xml:"rectangle" json:"rectangle"`
Structures []Structure `xml:"structures>structure" json:"structures"` Structures []Structure `xml:"structures>structure" json:"structures"`
OtherElements
EventObject EventObject
} }
@ -38,17 +46,30 @@ type Structure struct {
LocalId int `xml:"local_id" json:"localId"` LocalId int `xml:"local_id" json:"localId"`
Name string `xml:"name" json:"name"` Name string `xml:"name" json:"name"`
Type string `xml:"type" json:"type"` Type string `xml:"type" json:"type"`
OtherElements
EventObject
} }
type WorldConstruction struct { type WorldConstruction struct {
XMLName xml.Name `xml:"world_construction" json:"-"` XMLName xml.Name `xml:"world_construction" json:"-"`
NamedObject NamedObject
OtherElements
EventObject
} }
type Artifact struct { type Artifact struct {
XMLName xml.Name `xml:"artifact" json:"-"` XMLName xml.Name `xml:"artifact" json:"-"`
NamedObject NamedObject
SiteId int `xml:"site_id" json:"siteId"` SiteId int `xml:"site_id" json:"siteId"`
AbsTileX *int `xml:"abs_tile_x" json:"absTileX,omitempty"`
AbsTileY *int `xml:"abs_tile_y" json:"absTileY,omitempty"`
AbsTileZ *int `xml:"abs_tile_z" json:"absTileZ,omitempty"`
HolderHfid *int `xml:"holder_hfid" json:"holderHfid,omitempty" legend:"hf"`
// item object
StructureLocalId *int `xml:"structure_local_id" json:"structureLocalId,omitempty"`
SubregionId *int `xml:"subregion_id" json:"subregionId,omitempty"`
OtherElements
EventObject EventObject
} }
@ -56,8 +77,44 @@ type Artifact struct {
type HistoricalFigure struct { type HistoricalFigure struct {
XMLName xml.Name `xml:"historical_figure" json:"-"` XMLName xml.Name `xml:"historical_figure" json:"-"`
NamedObject NamedObject
Race string `xml:"race" json:"race"`
Caste string `xml:"caste" json:"caste"` Race *string `xml:"race" json:"race"`
// Caste *string `xml:"caste" json:"caste"`
// ActiveInteraction *[]string `xml:"active_interaction" json:"activeInteraction,omitempty"`
// Animated *string `xml:"animated" json:"animated,omitempty"`
// AnimatedString *string `xml:"animated_string" json:"animatedString,omitempty"`
// Appeared *int `xml:"appeared" json:"appeared,omitempty"`
// AssociatedType *string `xml:"associated_type" json:"associatedType,omitempty"`
// BirthSeconds72 *int `xml:"birth_seconds72" json:"birthSeconds72,omitempty"`
// BirthYear *int `xml:"birth_year" json:"birthYear,omitempty"`
// CurrentIdentityId *int `xml:"current_identity_id" json:"currentIdentityId,omitempty" legend:"entity"`
// DeathSeconds72 *int `xml:"death_seconds72" json:"deathSeconds72,omitempty"`
// DeathYear *int `xml:"death_year" json:"deathYear,omitempty"`
// Deity *string `xml:"deity" json:"deity,omitempty"`
// EntPopId *int `xml:"ent_pop_id" json:"entPopId,omitempty"`
// // entity_former_position_link object
// // entity_link object
// // entity_position_link object
// // entity_reputation object
// // entity_squad_link object
// Force *string `xml:"force" json:"force,omitempty"`
// Goal *[]string `xml:"goal" json:"goal,omitempty"`
// // hf_link object
// // hf_skill object
// HoldsArtifact *[]int `xml:"holds_artifact" json:"holdsArtifact,omitempty"`
// // honor_entity object
// InteractionKnowledge *[]string `xml:"interaction_knowledge" json:"interactionKnowledge,omitempty"`
// // intrigue_actor object
// // intrigue_plot object
// JourneyPet *[]string `xml:"journey_pet" json:"journeyPet,omitempty"`
// // relationship_profile_hf_historical object
// // relationship_profile_hf_visual object
// // site_link object
// // site_property object
// Sphere *[]string `xml:"sphere" json:"sphere,omitempty"`
// UsedIdentityId *[]int `xml:"used_identity_id" json:"usedIdentityId,omitempty" legend:"entity"`
// // vague_relationship object
OtherElements OtherElements
EventObject EventObject
@ -68,16 +125,113 @@ func (r *HistoricalFigure) Type() string { return "hf" }
type HistoricalEventCollection struct { type HistoricalEventCollection struct {
XMLName xml.Name `xml:"historical_event_collection" json:"-"` XMLName xml.Name `xml:"historical_event_collection" json:"-"`
NamedObject NamedObject
StartYear int `xml:"year"` Year int `xml:"year"`
StartSeconds int `xml:"seconds72"` Seconds int `xml:"seconds72"`
EndYear int `xml:"end_year"` EndYear int `xml:"end_year"`
EndSeconds int `xml:"end_seconds72"` EndSeconds int `xml:"end_seconds72"`
Type string `xml:"type" json:"type"` Type string `xml:"type" json:"type"`
EventIds []int `xml:"event" json:"eventIds"`
EventIds []int `xml:"event" json:"eventIds"`
AggressorEntId *int `xml:"aggressor_ent_id" json:"aggressorEntId,omitempty"`
AttackingEnid *int `xml:"attacking_enid" json:"attackingEnid,omitempty" legend:"entity"`
AttackingHfid *[]int `xml:"attacking_hfid" json:"attackingHfid,omitempty" legend:"hf"`
AttackingSquadDeaths *[]int `xml:"attacking_squad_deaths" json:"attackingSquadDeaths,omitempty"`
AttackingSquadEntityPop *[]int `xml:"attacking_squad_entity_pop" json:"attackingSquadEntityPop,omitempty"`
AttackingSquadNumber *[]int `xml:"attacking_squad_number" json:"attackingSquadNumber,omitempty"`
AttackingSquadRace *[]string `xml:"attacking_squad_race" json:"attackingSquadRace,omitempty"`
AttackingSquadSite *[]int `xml:"attacking_squad_site" json:"attackingSquadSite,omitempty"`
CivId *int `xml:"civ_id" json:"civId,omitempty" legend:"entity"`
Coords *string `xml:"coords" json:"coords,omitempty"`
DefenderEntId *int `xml:"defender_ent_id" json:"defenderEntId,omitempty"`
DefendingEnid *int `xml:"defending_enid" json:"defendingEnid,omitempty" legend:"entity"`
DefendingHfid *[]int `xml:"defending_hfid" json:"defendingHfid,omitempty" legend:"hf"`
DefendingSquadDeaths *[]int `xml:"defending_squad_deaths" json:"defendingSquadDeaths,omitempty"`
DefendingSquadEntityPop *[]int `xml:"defending_squad_entity_pop" json:"defendingSquadEntityPop,omitempty"`
DefendingSquadNumber *[]int `xml:"defending_squad_number" json:"defendingSquadNumber,omitempty"`
DefendingSquadRace *[]string `xml:"defending_squad_race" json:"defendingSquadRace,omitempty"`
DefendingSquadSite *[]int `xml:"defending_squad_site" json:"defendingSquadSite,omitempty"`
Eventcol *[]int `xml:"eventcol" json:"eventcol,omitempty"`
FeatureLayerId *int `xml:"feature_layer_id" json:"featureLayerId,omitempty"`
IndividualMerc *[]string `xml:"individual_merc" json:"individualMerc,omitempty"`
NoncomHfid *[]int `xml:"noncom_hfid" json:"noncomHfid,omitempty" legend:"hf"`
OccasionId *int `xml:"occasion_id" json:"occasionId,omitempty"`
Ordinal *int `xml:"ordinal" json:"ordinal,omitempty"`
Outcome *string `xml:"outcome" json:"outcome,omitempty"`
ParentEventcol *int `xml:"parent_eventcol" json:"parentEventcol,omitempty"`
SiteId *int `xml:"site_id" json:"siteId,omitempty" legend:"site"`
StartSeconds72 *int `xml:"start_seconds72" json:"startSeconds72,omitempty"`
StartYear *int `xml:"start_year" json:"startYear,omitempty"`
SubregionId *int `xml:"subregion_id" json:"subregionId,omitempty"`
WarEventcol *int `xml:"war_eventcol" json:"warEventcol,omitempty"`
ASupportMercEnid *int `xml:"a_support_merc_enid" json:"aSupportMercEnid,omitempty" legend:"entity"`
ASupportMercHfid *[]int `xml:"a_support_merc_hfid" json:"aSupportMercHfid,omitempty" legend:"hf"`
AttackingMercEnid *int `xml:"attacking_merc_enid" json:"attackingMercEnid,omitempty" legend:"entity"`
AttackingSquadAnimated *[]string `xml:"attacking_squad_animated" json:"attackingSquadAnimated,omitempty"`
CompanyMerc *[]string `xml:"company_merc" json:"companyMerc,omitempty"`
DSupportMercEnid *int `xml:"d_support_merc_enid" json:"dSupportMercEnid,omitempty" legend:"entity"`
DSupportMercHfid *[]int `xml:"d_support_merc_hfid" json:"dSupportMercHfid,omitempty" legend:"hf"`
DefendingMercEnid *int `xml:"defending_merc_enid" json:"defendingMercEnid,omitempty" legend:"entity"`
DefendingSquadAnimated *[]string `xml:"defending_squad_animated" json:"defendingSquadAnimated,omitempty"`
TargetEntityId *int `xml:"target_entity_id" json:"targetEntityId,omitempty" legend:"entity"`
OtherElements
} }
type Entity struct { type Entity struct {
XMLName xml.Name `xml:"entity" json:"-"` XMLName xml.Name `xml:"entity" json:"-"`
NamedObject NamedObject
OtherElements
EventObject
}
type EntityPopulation struct {
XMLName xml.Name `xml:"entity_population" json:"-"`
OtherElements
}
type HistoricalEra struct {
XMLName xml.Name `xml:"historical_era" json:"-"`
NamedObject
StartYear *int `xml:"start_year" json:"startYear,omitempty"`
OtherElements
}
type DanceForm struct {
XMLName xml.Name `xml:"dance_form" json:"-"`
ArtForm
}
type MusicalForm struct {
XMLName xml.Name `xml:"musical_form" json:"-"`
ArtForm
}
type PoeticForm struct {
XMLName xml.Name `xml:"poetic_form" json:"-"`
ArtForm
}
type WrittenContent struct {
XMLName xml.Name `xml:"written_content" json:"-"`
NamedObject
AuthorHfid *int `xml:"author_hfid" json:"authorHfid,omitempty" legend:"hf"`
AuthorRoll *int `xml:"author_roll" json:"authorRoll,omitempty"`
Form *string `xml:"form" json:"form,omitempty"`
FormId *int `xml:"form_id" json:"formId,omitempty"`
Style *[]string `xml:"style" json:"style,omitempty"`
Title *string `xml:"title" json:"title,omitempty"`
OtherElements
EventObject
}
type ArtForm struct {
NamedObject
Description *string `xml:"description" json:"description,omitempty"`
OtherElements
EventObject EventObject
} }

View File

@ -2,10 +2,12 @@ package model
import ( import (
"encoding/xml" "encoding/xml"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
"reflect" "reflect"
"strings"
) )
type World struct { type World struct {
@ -13,33 +15,62 @@ type World struct {
Name string `xml:"name"` Name string `xml:"name"`
AltName string `xml:"altname"` AltName string `xml:"altname"`
Regions []*Region `xml:"regions>region"` // Regions []*Region `xml:"regions>region"`
UndergroundRegions []*UndergroundRegion `xml:"underground_regions>underground_region"` // UndergroundRegions []*UndergroundRegion `xml:"underground_regions>underground_region"`
Landmasses []*Landmass `xml:"landmasses>landmass"` // Landmasses []*Landmass `xml:"landmasses>landmass"`
Sites []*Site `xml:"sites>site"` // Sites []*Site `xml:"sites>site"`
WorldConstructions []*WorldConstruction `xml:"world_constructions>world_construction"` // WorldConstructions []*WorldConstruction `xml:"world_constructions>world_construction"`
Artifacts []*Artifact `xml:"artifacts>artifact"` // Artifacts []*Artifact `xml:"artifacts>artifact"`
HistoricalFigures []*HistoricalFigure `xml:"historical_figures>historical_figure"` // HistoricalFigures []*HistoricalFigure //`xml:"historical_figures>historical_figure"`
HistoricalEvents []*HistoricalEvent `xml:"historical_events>historical_event"` // HistoricalEvents []*HistoricalEvent //`xml:"historical_events>historical_event"`
HistoricalEventCollections []*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"` // HistoricalEventCollections []*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"`
Entities []*Entity `xml:"entities>entity"` // HistoricalEras []*HistoricalEra `xml:"historical_eras>historical_era"`
// Entities []*Entity `xml:"entities>entity"`
// EntityPopulations []*EntityPopulation `xml:"entity_populations>entity_population"`
// DanceForms []*DanceForm `xml:"dance_forms>dance_form"`
// MusicalForms []*MusicalForm `xml:"musical_forms>musical_form"`
// PoeticForms []*PoeticForm `xml:"poetic_forms>poetic_form"`
// WrittenContents []*WrittenContent `xml:"written_contents>written_content"`
OtherElements
RegionMap map[int]*Region RegionMap map[int]*Region `xml:"regions>region"`
UndergroundRegionMap map[int]*UndergroundRegion UndergroundRegionMap map[int]*UndergroundRegion `xml:"underground_regions>underground_region"`
LandmassMap map[int]*Landmass LandmassMap map[int]*Landmass `xml:"landmasses>landmass"`
SiteMap map[int]*Site SiteMap map[int]*Site `xml:"sites>site"`
WorldConstructionMap map[int]*WorldConstruction WorldConstructionMap map[int]*WorldConstruction `xml:"world_constructions>world_construction"`
ArtifactMap map[int]*Artifact ArtifactMap map[int]*Artifact `xml:"artifacts>artifact"`
HistoricalFigureMap map[int]*HistoricalFigure HistoricalFigureMap map[int]*HistoricalFigure `xml:"historical_figures>historical_figure"`
HistoricalEventMap map[int]*HistoricalEvent HistoricalEventMap map[int]*HistoricalEvent `xml:"historical_events>historical_event"`
HistoricalEventCollectionMap map[int]*HistoricalEventCollection HistoricalEventCollectionMap map[int]*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"`
EntityMap map[int]*Entity HistoricalEraMap map[int]*HistoricalEra `xml:"historical_eras>historical_era"`
EntityMap map[int]*Entity `xml:"entities>entity"`
DanceFormMap map[int]*DanceForm `xml:"dance_forms>dance_form"`
MusicalFormMap map[int]*MusicalForm //`xml:"musical_forms>musical_form"`
PoeticFormMap map[int]*PoeticForm // `xml:"poetic_forms>poetic_form"`
WrittenContentMap map[int]*WrittenContent `xml:"written_contents>written_content"`
} }
var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ CueaaaaceeeiiiAAEaAooouuyOU faiounN ") var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ CueaaaaceeeiiiAAEaAooouuyOU faiounN ")
// var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑ ") // var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑ ")
type ConvertReader struct {
r io.Reader
read int
}
func (c *ConvertReader) Read(b []byte) (n int, err error) {
n, err = c.r.Read(b)
if c.read == 0 && n > 35 {
copy(b[30:35], []byte("UTF-8"))
}
c.read += n
for i := range b {
b[i] = cp437[b[i]]
}
return n, err
}
func (w *World) Load(file string) { func (w *World) Load(file string) {
xmlFile, err := os.Open(file) xmlFile, err := os.Open(file)
if err != nil { if err != nil {
@ -49,51 +80,198 @@ func (w *World) Load(file string) {
fmt.Println("Successfully Opened users.xml") fmt.Println("Successfully Opened users.xml")
defer xmlFile.Close() defer xmlFile.Close()
byteValue, _ := io.ReadAll(xmlFile) converter := &ConvertReader{r: xmlFile}
fmt.Println(len(byteValue))
copy(byteValue[30:35], []byte("UTF-8")) // byteValue, _ := io.ReadAll(converter)
for i := range byteValue { // fmt.Println(len(byteValue))
byteValue[i] = cp437[byteValue[i]]
}
err = xml.Unmarshal(byteValue, w) fillTypes(reflect.TypeOf(w))
if err != nil { fmt.Println(types["Region"])
fmt.Println(err)
} d := xml.NewDecoder(converter)
parseObject(d, nil, reflect.ValueOf(w))
// err = xml.Unmarshal(byteValue, w)
// if err != nil {
// fmt.Println(err)
// }
fmt.Println("World loaded") fmt.Println("World loaded")
} }
var types = make(map[string]map[string]reflect.StructField)
func fillTypes(t reflect.Type) {
if t.Kind() == reflect.Pointer {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return
}
fmt.Println(t.Name())
if _, ok := types[t.Name()]; ok {
return
}
info := make(map[string]reflect.StructField)
DeepFields(t, &info, make([]int, 0))
types[t.Name()] = info
}
func DeepFields(t reflect.Type, info *map[string]reflect.StructField, index []int) {
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
f.Index = append(index, f.Index[0])
if xml, ok := f.Tag.Lookup("xml"); ok {
if p := strings.Index(xml, ">"); p >= 0 {
(*info)[xml[0:p]] = f
} else {
for _, s := range strings.Split(xml, "|") {
(*info)[s] = f
}
}
if f.Type.Kind() == reflect.Map || f.Type.Kind() == reflect.Slice {
fillTypes(f.Type.Elem())
}
fmt.Println(i, f)
}
if f.Type.Kind() == reflect.Struct && f.Anonymous {
DeepFields(f.Type, info, f.Index)
}
}
}
func parseObject(d *xml.Decoder, start *xml.StartElement, val reflect.Value) error {
if start == nil {
for {
tok, err := d.Token()
if err != nil {
return err
}
if t, ok := tok.(xml.StartElement); ok {
start = &t
break
}
}
}
if val.Kind() == reflect.Pointer {
val = val.Elem()
}
typ, ok := types[val.Type().Name()]
if !ok {
d.Skip()
return nil
}
Loop:
for {
tok, err := d.Token()
if err != nil {
return err
}
switch t := tok.(type) {
case xml.StartElement:
if ty, ok := typ[t.Name.Local]; ok {
if ty.Type.Kind() == reflect.Map {
fmt.Println(" ", t.Name.Local, val.Type().Name(), ty)
f := val.Field(ty.Index[0])
if f.IsNil() {
f.Set(reflect.MakeMapWithSize(ty.Type, 0))
}
parseMap(d, ty, f)
val.Field(ty.Index[0]).SetMapIndex(reflect.ValueOf(6), reflect.New(ty.Type.Elem().Elem()))
}
} else {
d.Skip()
}
// parseObject(d, &t, val)
case xml.EndElement:
break Loop
}
}
return nil
}
func parseMap(d *xml.Decoder, field reflect.StructField, dest reflect.Value) error {
x, ok := field.Tag.Lookup("xml")
if !ok {
return errors.New("no xml tag")
}
elementName := strings.Split(x, ">")[1]
var lastStart *xml.StartElement
var id int
Loop:
for {
tok, err := d.Token()
if err != nil {
return err
}
switch t := tok.(type) {
case xml.StartElement:
if t.Name.Local == elementName {
lastStart = &t
id = -1
} else if t.Name.Local == "id" {
if id != -1 {
return errors.New("ID at invalid place")
}
d.DecodeElement(&id, &t)
obj := dest.MapIndex(reflect.ValueOf(id))
if !obj.IsValid() {
obj = reflect.New(field.Type.Elem().Elem())
dest.SetMapIndex(reflect.ValueOf(id), obj)
obj.Elem().FieldByIndex(types[obj.Type().Elem().Name()]["id"].Index).SetInt(int64(id))
}
d.DecodeElement(obj.Interface(), lastStart)
} else {
fmt.Println("SKIP", elementName, t.Name.Local)
d.Skip()
}
case xml.EndElement:
if t.Name.Local != elementName {
break Loop
}
}
}
return nil
}
func (w *World) Process() { func (w *World) Process() {
w.RegionMap = make(map[int]*Region) // w.RegionMap = make(map[int]*Region)
mapObjects(&w.Regions, &w.RegionMap) // mapObjects(&w.Regions, &w.RegionMap)
w.UndergroundRegionMap = make(map[int]*UndergroundRegion) // w.UndergroundRegionMap = make(map[int]*UndergroundRegion)
mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap) // mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap)
w.LandmassMap = make(map[int]*Landmass) // w.LandmassMap = make(map[int]*Landmass)
mapObjects(&w.Landmasses, &w.LandmassMap) // mapObjects(&w.Landmasses, &w.LandmassMap)
w.SiteMap = make(map[int]*Site) // w.SiteMap = make(map[int]*Site)
mapObjects(&w.Sites, &w.SiteMap) // mapObjects(&w.Sites, &w.SiteMap)
w.WorldConstructionMap = make(map[int]*WorldConstruction) // w.WorldConstructionMap = make(map[int]*WorldConstruction)
mapObjects(&w.WorldConstructions, &w.WorldConstructionMap) // mapObjects(&w.WorldConstructions, &w.WorldConstructionMap)
w.ArtifactMap = make(map[int]*Artifact) // w.ArtifactMap = make(map[int]*Artifact)
mapObjects(&w.Artifacts, &w.ArtifactMap) // mapObjects(&w.Artifacts, &w.ArtifactMap)
w.HistoricalFigureMap = make(map[int]*HistoricalFigure) // w.HistoricalFigureMap = make(map[int]*HistoricalFigure)
mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap) // mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap)
w.HistoricalEventMap = make(map[int]*HistoricalEvent) // w.HistoricalEventMap = make(map[int]*HistoricalEvent)
mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap) // mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap)
w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection) // w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection)
mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap) // mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap)
w.EntityMap = make(map[int]*Entity) // w.EntityMap = make(map[int]*Entity)
mapObjects(&w.Entities, &w.EntityMap) // mapObjects(&w.Entities, &w.EntityMap)
w.processEvents() w.processEvents()
} }
@ -110,16 +288,16 @@ func (w *World) processEvents() {
} }
} }
for eventIndex := 0; eventIndex < len(w.HistoricalEvents); eventIndex++ { // for eventIndex := 0; eventIndex < len(w.HistoricalEvents); eventIndex++ {
e := w.HistoricalEvents[eventIndex] // e := w.HistoricalEvents[eventIndex]
v := reflect.ValueOf(*e) // v := reflect.ValueOf(*e)
processEvent(e, &v, legendFields["entity"], &w.EntityMap) // processEvent(e, &v, legendFields["entity"], &w.EntityMap)
processEvent(e, &v, legendFields["site"], &w.SiteMap) // processEvent(e, &v, legendFields["site"], &w.SiteMap)
processEvent(e, &v, legendFields["hf"], &w.HistoricalFigureMap) // processEvent(e, &v, legendFields["hf"], &w.HistoricalFigureMap)
processEvent(e, &v, legendFields["artifact"], &w.ArtifactMap) // processEvent(e, &v, legendFields["artifact"], &w.ArtifactMap)
// processEvent(e, &v, legendFields["wc"], &w.WorldConstructionMap) // // processEvent(e, &v, legendFields["wc"], &w.WorldConstructionMap)
// processEvent(e, &v, legendFields["structure"], &w.St) // // processEvent(e, &v, legendFields["structure"], &w.St)
} // }
} }
func processEvent[T HasEvents](event *HistoricalEvent, v *reflect.Value, fields []int, objectMap *map[int]T) { func processEvent[T HasEvents](event *HistoricalEvent, v *reflect.Value, fields []int, objectMap *map[int]T) {
@ -130,15 +308,13 @@ func processEvent[T HasEvents](event *HistoricalEvent, v *reflect.Value, fields
case reflect.Slice: case reflect.Slice:
ids := val.Interface().(*[]int) ids := val.Interface().(*[]int)
for _, id := range *ids { for _, id := range *ids {
x, ok := (*objectMap)[id] if x, ok := (*objectMap)[id]; ok {
if ok {
x.SetEvents(append(x.GetEvents(), event)) x.SetEvents(append(x.GetEvents(), event))
} }
} }
case reflect.Int: case reflect.Int:
id := int(val.Elem().Int()) id := int(val.Elem().Int())
x, ok := (*objectMap)[id] if x, ok := (*objectMap)[id]; ok {
if ok {
x.SetEvents(append(x.GetEvents(), event)) x.SetEvents(append(x.GetEvents(), event))
} }
default: default:

View File

@ -31,11 +31,7 @@ func RegisterResource[T model.Named](router *mux.Router, resourceName string, re
fmt.Println(err) fmt.Println(err)
} }
for _, item := range resources { json.NewEncoder(w).Encode(resources[id])
if item.Id() == id {
json.NewEncoder(w).Encode(item)
}
}
} }
router.HandleFunc(fmt.Sprintf("/api/%s", resourceName), list).Methods("GET") router.HandleFunc(fmt.Sprintf("/api/%s", resourceName), list).Methods("GET")