From 033fb5fee685a42e17b6aba47fb1063139963151 Mon Sep 17 00:00:00 2001 From: mlange-42 Date: Wed, 26 Jun 2024 16:26:25 +0200 Subject: [PATCH 1/3] Read parameters from JSON string in addition to a file --- CHANGELOG.md | 5 +++++ params/custom.go | 20 ++++++++++++++------ params/default.go | 23 +++++++++++++++++------ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd46e2e..ca577c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ ## [[unpublished]](https://github.com/mlange-42/beecs/compare/v0.2.0...main) +### Breaking changes + +* `FromJSON` for default and custom parameters renamed to `FromJSONFile` (#77) + ### Features - Adds option to terminate on extinction of all bees (#75) - Adds observer `Extinction` to report the tick of colony extinction (#76) +- Adds `FromJSON([]byte)` for default and custom parameters (#77) ### Documentation diff --git a/params/custom.go b/params/custom.go index 8b83685..912e235 100644 --- a/params/custom.go +++ b/params/custom.go @@ -38,24 +38,32 @@ type customParamsJs struct { Custom map[string]entry } -// FromJSON fills the parameter set with values from a JSON file. +// FromJSONFile fills the parameter set with values from a JSON file. // // Only values present in the file are overwritten, // all other values remain unchanged. -func (p *CustomParams) FromJSON(path string) error { - file, err := os.Open(path) +func (p *CustomParams) FromJSONFile(path string) error { + content, err := os.ReadFile(path) if err != nil { return err } - defer file.Close() - decoder := json.NewDecoder(file) + return p.FromJSON(content) +} + +// FromJSON fills the parameter set with values from JSON. +// +// Only values present in the file are overwritten, +// all other values remain unchanged. +func (p *CustomParams) FromJSON(data []byte) error { + reader := bytes.NewReader(data) + decoder := json.NewDecoder(reader) decoder.DisallowUnknownFields() pars := customParamsJs{ Parameters: p.Parameters, } - err = decoder.Decode(&pars) + err := decoder.Decode(&pars) if err != nil { return err } diff --git a/params/default.go b/params/default.go index 589d637..797a4a3 100644 --- a/params/default.go +++ b/params/default.go @@ -1,6 +1,7 @@ package params import ( + "bytes" "encoding/json" "math/rand" "os" @@ -15,7 +16,9 @@ type Params interface { // Apply the parameters to a world. Apply(world *ecs.World) // FromJSON fills the parameter set with values from a JSON file. - FromJSON(path string) error + FromJSONFile(path string) error + // FromJSON fills the parameter set with values from a JSON file. + FromJSON(data []byte) error } // DefaultParams contains all default parameters of BEEHAVE. @@ -198,18 +201,26 @@ func Default() DefaultParams { } } -// FromJSON fills the parameter set with values from a JSON file. +// unchanged fills the parameter set with values from a JSON file. // // Only values present in the file are overwritten, // all other values remain unchanged. -func (p *DefaultParams) FromJSON(path string) error { - file, err := os.Open(path) +func (p *DefaultParams) FromJSONFile(path string) error { + content, err := os.ReadFile(path) if err != nil { return err } - defer file.Close() - decoder := json.NewDecoder(file) + return p.FromJSON(content) +} + +// FromJSON fills the parameter set with values from JSON. +// +// Only values present in the file are overwritten, +// all other values remain unchanged. +func (p *DefaultParams) FromJSON(data []byte) error { + reader := bytes.NewReader(data) + decoder := json.NewDecoder(reader) decoder.DisallowUnknownFields() return decoder.Decode(p) } From 9a538da6323ef03bf5798eb46658c36fc69b23c8 Mon Sep 17 00:00:00 2001 From: mlange-42 Date: Wed, 26 Jun 2024 16:40:34 +0200 Subject: [PATCH 2/3] add tests for json parsing of parameters --- params/custom_test.go | 47 ++++++++++++++++++++++++++++++++++++++++++ params/default_test.go | 24 +++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 params/custom_test.go create mode 100644 params/default_test.go diff --git a/params/custom_test.go b/params/custom_test.go new file mode 100644 index 0000000..431d3d1 --- /dev/null +++ b/params/custom_test.go @@ -0,0 +1,47 @@ +package params_test + +import ( + "reflect" + "testing" + + "github.com/mlange-42/beecs/params" + "github.com/mlange-42/beecs/registry" + "github.com/stretchr/testify/assert" +) + +type CustomParam struct { + Value int +} + +func TestCustomParamsFromJSON(t *testing.T) { + registry.RegisterResource[CustomParam]() + + p := params.CustomParams{} + + js := `{ + "Parameters": { + "Termination": { + "MaxTicks": 3650, + "OnExtinction": true + } + }, + "Custom": { + "params_test.CustomParam": { + "Value": 100 + } + } +}` + + err := p.FromJSON([]byte(js)) + assert.Nil(t, err) + + assert.Equal(t, 3650, p.Parameters.Termination.MaxTicks) + + obj, ok := p.Custom[reflect.TypeOf(CustomParam{})] + assert.True(t, ok) + + par, ok := obj.(*CustomParam) + assert.True(t, ok) + + assert.Equal(t, 100, par.Value) +} diff --git a/params/default_test.go b/params/default_test.go new file mode 100644 index 0000000..637fe3a --- /dev/null +++ b/params/default_test.go @@ -0,0 +1,24 @@ +package params_test + +import ( + "testing" + + "github.com/mlange-42/beecs/params" + "github.com/stretchr/testify/assert" +) + +func TestDefaultParamsFromJSON(t *testing.T) { + p := params.Default() + + js := `{ + "Termination": { + "MaxTicks": 3650, + "OnExtinction": true + } +}` + + err := p.FromJSON([]byte(js)) + assert.Nil(t, err) + + assert.Equal(t, 3650, p.Termination.MaxTicks) +} From fa499d680a9518165cebb3edda2b068c46d614f9 Mon Sep 17 00:00:00 2001 From: mlange-42 Date: Wed, 26 Jun 2024 16:44:45 +0200 Subject: [PATCH 3/3] fix JSON example --- _examples/json_parameters/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_examples/json_parameters/main.go b/_examples/json_parameters/main.go index f9bd46d..20904d8 100644 --- a/_examples/json_parameters/main.go +++ b/_examples/json_parameters/main.go @@ -15,7 +15,7 @@ func main() { // Get the default parameters. p := params.Default() // Read JSON to modify some parameters. - err := p.FromJSON("_examples/json_parameters/params.json") + err := p.FromJSONFile("_examples/json_parameters/params.json") if err != nil { log.Fatal(err) }