package budget2 type Instance struct { ID int `json:"i"` Value map[string]interface{} `json:"v"` Cache map[string]interface{} `json:"-"` } type Interface interface { Name(context *Context) string DefaultValue() map[string]interface{} ControlNames(context *Context) []string Controls(i Interface, context *Context) []Control GetValue(i Interface, name string, context *Context) interface{} GetControl(name string, context *Context) *Control Handle(i Interface, context *Context, name string, typ string, value interface{}) error } type Object struct { } func (Object) Name(context *Context) string { return "" } func (Object) DefaultValue() map[string]interface{} { return map[string]interface{}{} } func (Object) ControlNames(context *Context) []string { return []string{} } func (Object) Controls(i Interface, context *Context) []Control { controls := make([]Control, 0) for _, name := range i.ControlNames(context) { control := i.GetControl(name, context) if control != nil { controls = append(controls, *control) } } return controls } func (Object) GetValue(i Interface, name string, context *Context) interface{} { if value, ok := context.CurrentInstance().Value[name]; ok { return value } if value, ok := i.DefaultValue()[name]; ok { context.CurrentInstance().Value[name] = value return value } if value, ok := context.CurrentInstance().Cache[name]; ok { context.CurrentInstance().Value[name] = value return value } return nil } func (Object) GetControl(name string, context *Context) *Control { return nil } func (Object) Handle(i Interface, context *Context, name string, typ string, value interface{}) error { control := i.GetControl(name, context) if control != nil { context.CurrentInstance().Value[name] = control.Handle(typ, value, context) } return nil }