Skip to content

Board identification improvements #1674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 18, 2022
Prev Previous commit
Next Next commit
Board's build options properties are now calculated only once and cached
  • Loading branch information
cmaglie committed Oct 14, 2022
commit db2a3d15bb8945b80c886daa5797b782cc49b680
68 changes: 33 additions & 35 deletions arduino/cores/board.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import (

// Board represents a board loaded from an installed platform
type Board struct {
BoardID string
Properties *properties.Map `json:"-"`
PlatformRelease *PlatformRelease `json:"-"`
configOptions *properties.Map
configOptionValues map[string]*properties.Map
identificationProperties []*properties.Map
BoardID string
Properties *properties.Map `json:"-"`
PlatformRelease *PlatformRelease `json:"-"`
configOptions *properties.Map
configOptionValues map[string]*properties.Map
configOptionProperties map[string]*properties.Map
defaultConfig *properties.Map
identificationProperties []*properties.Map
}

// HasUsbID returns true if the board match the usb vid and pid parameters
Expand Down Expand Up @@ -78,11 +80,16 @@ func (b *Board) buildConfigOptionsStructures() {
}

b.configOptionValues = map[string]*properties.Map{}
for configName, options := range allConfigs.FirstLevelOf() {
b.configOptionValues[configName] = properties.NewMap()
for _, value := range options.FirstLevelKeys() {
if label, ok := options.GetOk(value); ok {
b.configOptionValues[configName].Set(value, label)
b.configOptionProperties = map[string]*properties.Map{}
b.defaultConfig = properties.NewMap()
for option, optionProps := range allConfigs.FirstLevelOf() {
b.configOptionValues[option] = properties.NewMap()
values := optionProps.FirstLevelKeys()
b.defaultConfig.Set(option, values[0])
for _, value := range values {
if label, ok := optionProps.GetOk(value); ok {
b.configOptionValues[option].Set(value, label)
b.configOptionProperties[option+"="+value] = optionProps.SubTree(value)
}
}
}
Expand All @@ -106,38 +113,29 @@ func (b *Board) GetConfigOptionValues(option string) *properties.Map {
// GetBuildProperties returns the build properties and the build
// platform for the Board with the configuration passed as parameter.
func (b *Board) GetBuildProperties(userConfigs *properties.Map) (*properties.Map, error) {
// Clone user configs because they are destroyed during iteration
userConfigs = userConfigs.Clone()
b.buildConfigOptionsStructures()

// Override default configs with user configs
config := b.defaultConfig.Clone()
config.Merge(userConfigs)

// Start with board's base properties
buildProperties := b.Properties.Clone()

// Add all sub-configurations one by one (a config is: option=value)
menu := b.Properties.SubTree("menu")
for _, option := range menu.FirstLevelKeys() {
optionMenu := menu.SubTree(option)
userValue, haveUserValue := userConfigs.GetOk(option)
if haveUserValue {
userConfigs.Remove(option)
if !optionMenu.ContainsKey(userValue) {
return nil, fmt.Errorf(tr("invalid value '%[1]s' for option '%[2]s'"), userValue, option)
}
} else {
// apply default
userValue = optionMenu.FirstLevelKeys()[0]
}

optionsConf := optionMenu.SubTree(userValue)
buildProperties.Merge(optionsConf)
}

// Check for residual invalid options...
if invalidKeys := userConfigs.Keys(); len(invalidKeys) > 0 {
invalidOption := invalidKeys[0]
if invalidOption == "" {
for option, value := range config.AsMap() {
if option == "" {
return nil, fmt.Errorf(tr("invalid empty option found"))
}
return nil, fmt.Errorf(tr("invalid option '%s'"), invalidOption)
if _, ok := b.configOptions.GetOk(option); !ok {
return nil, fmt.Errorf(tr("invalid option '%s'"), option)
}
optionsConf, ok := b.configOptionProperties[option+"="+value]
if !ok {
return nil, fmt.Errorf(tr("invalid value '%[1]s' for option '%[2]s'"), value, option)
}
buildProperties.Merge(optionsConf)
}

return buildProperties, nil
Expand Down
8 changes: 8 additions & 0 deletions arduino/cores/board_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var boardUno = &Board{
Name: "arduino",
},
},
Menus: properties.NewMap(),
},
}

Expand Down Expand Up @@ -114,6 +115,9 @@ var boardMega = &Board{
Name: "arduino",
},
},
Menus: properties.NewFromHashmap(map[string]string{
"cpu": "Processor",
}),
},
}

Expand Down Expand Up @@ -154,6 +158,10 @@ var boardWatterottTiny841 = &Board{
Name: "watterott",
},
},
Menus: properties.NewFromHashmap(map[string]string{
"core": "Core",
"info": "Info",
}),
},
}

Expand Down