1
0
Fork 0

Reflect magic

This commit is contained in:
Gregory Eremin 2015-08-29 21:51:12 +03:00
parent d1131d158f
commit be052e2c75
2 changed files with 27 additions and 7 deletions

View File

@ -4,6 +4,8 @@ import (
"flag" "flag"
"log" "log"
"github.com/kr/pretty"
"github.com/localhots/secondly" "github.com/localhots/secondly"
) )
@ -40,8 +42,9 @@ func main() {
// Starting a web server // Starting a web server
secondly.StartServer("", 5500) secondly.StartServer("", 5500)
// Defining callbacks // Defining callbacks
secondly.OnChange("AppName", func(o, n interface{}) { secondly.OnChange("app_name", func(o, n interface{}) {
log.Printf("OMG! AppName changed from %q to %q", o, n) log.Printf("OMG! AppName changed from %q to %q", o, n)
pretty.Println(conf)
}) })
// Other application startup logic // Other application startup logic

View File

@ -39,7 +39,7 @@ func Manage(target interface{}) {
panic("Argument must be a pointer to a struct") panic("Argument must be a pointer to a struct")
} }
config = target assign(target)
bootstrap() bootstrap()
} }
@ -109,6 +109,17 @@ func OnChange(field string, fun func(oldVal, newVal interface{})) {
callbacks[field] = append(callbacks[field], fun) callbacks[field] = append(callbacks[field], fun)
} }
func assign(target interface{}) {
if config == nil {
config = target
return
}
cval := reflect.ValueOf(config).Elem()
tval := reflect.ValueOf(target).Elem()
cval.Set(tval)
}
func bootstrap() { func bootstrap() {
if configFile == "" { if configFile == "" {
log.Fatalln("path to config file is not set") log.Fatalln("path to config file is not set")
@ -136,16 +147,20 @@ func writeConfig() {
} }
func updateConfig(body []byte) { func updateConfig(body []byte) {
// Making a copy of old config for further comparison
old := duplicate(config)
// Making a second copy that we will fill with new data
dupe := duplicate(config) dupe := duplicate(config)
if err := json.Unmarshal(body, dupe); err != nil { if err := json.Unmarshal(body, dupe); err != nil {
panic("Failed to update config") panic("Failed to update config")
return return
} }
defer triggerCallbacks(config, dupe)
// Setting new config // Setting new config
config = dupe assign(dupe)
triggerCallbacks(old, dupe)
} }
func marshal(obj interface{}) []byte { func marshal(obj interface{}) []byte {
@ -210,7 +225,9 @@ func duplicate(original interface{}) interface{} {
// Now we need the type (name) of this struct // Now we need the type (name) of this struct
typ := val.Type() typ := val.Type()
// Creating a duplicate instance of that struct // Creating a duplicate instance of that struct
dupe := reflect.New(typ).Interface() dupe := reflect.New(typ)
// Value copy
dupe.Elem().Set(val)
return dupe return dupe.Interface()
} }