All block states' properties are parsed and all enums represented as byte

This commit is contained in:
Tnze
2022-03-11 14:02:21 +08:00
parent 442993d3b1
commit a05f8e0a33
17 changed files with 1954 additions and 760 deletions

View File

@ -1,7 +1,10 @@
package main
import (
"bytes"
"compress/gzip"
_ "embed"
"go/format"
"log"
"os"
"strings"
@ -20,7 +23,7 @@ var temp = template.Must(template.
"UpperTheFirst": UpperTheFirst,
"ToGoTypeName": ToGoTypeName,
"GetType": GetType,
"Generator": func() string { return "generator/main.go" },
"Generator": func() string { return "generator/blocks/main.go" },
}).
Parse(tempSource))
@ -45,25 +48,31 @@ func readBlockStates(states *[]State) {
}
defer f.Close()
r, err := gzip.NewReader(f)
if err != nil {
log.Panic(err)
}
// parse the nbt format
if _, err := nbt.NewDecoder(f).Decode(states); err != nil {
if _, err := nbt.NewDecoder(r).Decode(states); err != nil {
log.Panic(err)
}
}
func genSourceFile(states []State) {
file, err := os.Create("blocks.go")
if err != nil {
var source bytes.Buffer
if err := temp.Execute(&source, states); err != nil {
log.Panic(err)
}
defer file.Close()
// clean up the file
if err := file.Truncate(0); err != nil {
return
}
if err := temp.Execute(file, states); err != nil {
log.Panic(err)
formattedSource, err := format.Source(source.Bytes())
if err != nil {
panic(err)
}
err = os.WriteFile("blocks.go", formattedSource, 0666)
if err != nil {
panic(err)
}
}
@ -79,7 +88,6 @@ func ToGoTypeName(name string) string {
var typeMaps = map[string]string{
"BooleanProperty": "Boolean",
"DirectionProperty": "Direction",
"EnumProperty": "string",
"IntegerProperty": "Integer",
}

View File

@ -0,0 +1,97 @@
package main
import (
"bytes"
_ "embed"
"go/format"
"log"
"os"
"strings"
"text/template"
"unicode"
)
type EnumProperty struct {
Name string
TrimPrefix bool
Values []string
}
var EnumProperties = []EnumProperty{
{Name: "AttachFace", Values: []string{"floor", "wall", "ceiling"}},
{Name: "BambooLeaves", Values: []string{"none", "small", "large"}},
{Name: "BedPart", Values: []string{"head", "foot"}},
{Name: "BellAttachType", Values: []string{"floor", "ceiling", "single_wall", "double_wall"}},
{Name: "ChestType", Values: []string{"single", "left", "right"}},
{Name: "ComparatorMode", Values: []string{"compare", "subtract"}},
{Name: "Direction", TrimPrefix: true, Values: []string{"down", "up", "north", "south", "west", "east"}},
{Name: "Axis", TrimPrefix: true, Values: []string{"x", "y", "z"}},
{Name: "DoorHingeSide", Values: []string{"left", "right"}},
{Name: "DoubleBlockHalf", Values: []string{"upper", "lower"}},
{Name: "DripstoneThickness", Values: []string{"tip_merge", "tip", "frustum", "middle", "base"}},
{Name: "Half", TrimPrefix: true, Values: []string{"top", "bottom"}},
{Name: "NoteBlockInstrument", Values: []string{
"harp", "basedrum", "snare", "hat",
"bass", "flute", "bell", "guitar",
"chime", "xylophone", "iron_xylophone", "cow_bell",
"didgeridoo", "bit", "banjo", "pling",
}},
{Name: "PistonType", Values: []string{"normal", "sticky"}},
{Name: "RailShape", Values: []string{
"north_south", "east_west",
"ascending_east", "ascending_west", "ascending_north", "ascending_south",
"south_east", "south_west", "north_west", "north_east",
}},
{Name: "RedstoneSide", Values: []string{"up", "side", "none"}},
{Name: "SculkSensorPhase", Values: []string{"inactive", "active", "cooldown"}},
{Name: "SlabType", Values: []string{"top", "bottom", "double"}},
{Name: "StairsShape", Values: []string{"straight", "inner_left", "inner_right", "outer_left", "outer_right"}},
{Name: "StructureMode", Values: []string{"save", "load", "corner", "data"}},
{Name: "Tilt", Values: []string{"none", "unstable", "partial", "full"}},
{Name: "WallSide", Values: []string{"none", "low", "tall"}},
{Name: "FrontAndTop", TrimPrefix: true, Values: []string{
"down_east", "down_north", "down_south", "down_west",
"up_east", "up_north", "up_south", "up_west",
"west_up", "east_up", "north_up", "south_up",
}},
}
//go:embed properties_enum.go.tmpl
var tempSource string
func main() {
var source bytes.Buffer
err := template.Must(template.
New("properties_enum").
Funcs(template.FuncMap{
"UpperTheFirst": UpperTheFirst,
"ToLower": strings.ToLower,
"Generator": func() string { return "generator/properties/main.go" },
}).
Parse(tempSource)).
Execute(&source, EnumProperties)
if err != nil {
log.Panic(err)
}
formattedSource, err := format.Source(source.Bytes())
if err != nil {
log.Panic(err)
}
err = os.WriteFile("properties_enum.go", formattedSource, 0666)
if err != nil {
log.Panic(err)
}
}
func UpperTheFirst(word string) string {
var sb strings.Builder
for _, word := range strings.Split(word, "_") {
runes := []rune(word)
if len(runes) > 0 {
runes[0] = unicode.ToUpper(runes[0])
}
sb.WriteString(string(runes))
}
return sb.String()
}

View File

@ -0,0 +1,45 @@
// Code generated by {{Generator}}; DO NOT EDIT.
package block
import (
"errors"
"strconv"
)
{{range $prop := .}}
type {{.Name}} byte
const (
{{- range $index, $element := .Values}}
{{if not $prop.TrimPrefix}}{{$prop.Name}}{{end}}{{$element | UpperTheFirst}}{{if eq $index 0 }} {{$prop.Name}} = iota{{end}}
{{- end}}
)
{{- $v := slice (.Name | ToLower) 0 1 }}
var str{{.Name}} = [...]string{ {{- range $index, $elem := .Values }}{{$elem | printf "%q"}}{{if ne $index (len $prop.Values)}}, {{end}}{{end -}} }
func ({{$v}} {{.Name}}) String() string {
if int({{$v}}) < len(str{{.Name}}) {
return str{{.Name}}[{{$v}}]
}
return "invalid {{.Name}}"
}
func ({{$v}} {{.Name}}) MarshalText() (text []byte, err error) {
if int({{$v}}) < len(str{{.Name}}) {
return []byte(str{{.Name}}[{{$v}}]), nil
}
return nil, errors.New("invalid {{.Name}}: " + strconv.Itoa(int({{$v}})))
}
func ({{$v}} *{{.Name}}) UnmarshalText(text []byte) error {
switch str := string(text); str {
{{- range .Values}}
case {{. | printf "%q"}}:
*{{$v}} = {{if not $prop.TrimPrefix}}{{$prop.Name}}{{end}}{{. | UpperTheFirst}}
{{- end}}
default:
return errors.New("unknown {{.Name}}: " + str)
}
return nil
}
{{end}}