// ClosureNew creates a new GClosure and adds its callback function // to the internally-maintained map. It's exported for visibility to other // gotk3 packages and shouldn't be used in application code. func ClosureNew(f interface{}, marshalData ...interface{}) (*C.GClosure, error) { // Create a reflect.Value from f. This is called when the // returned GClosure runs. rf := reflect.ValueOf(f) // Create closure context which points to the reflected func. cc := closureContext{rf: rf} // Closures can only be created from funcs. if rf.Type().Kind() != reflect.Func { return nil, errors.New("value is not a func") } if len(marshalData) > 0 { rv := reflect.ValueOf(marshalData[0]) cc.userData = &rv } c := C._g_closure_new() // Associate the GClosure with rf. rf will be looked up in this // map by the closure when the closure runs. closures.Lock() closures.m[c] = cc closures.Unlock() return c, nil }
// ClosureNew creates a new GClosure and adds its callback function // to the internally-maintained map. It's exported for visibility to other // gotk3 packages and shouldn't be used in application code. func ClosureNew(f interface{}, marshalData ...interface{}) (*C.GClosure, error) { // Create a reflect.Value from f. This is called when the // returned GClosure runs. rf := reflect.ValueOf(f) // Closures can only be created from funcs. if rf.Type().Kind() != reflect.Func { return nil, errors.New("value is not a func") } var c *C.GClosure if len(marshalData) == 0 { c = C._g_closure_new() } else { p, err := reflectGValue(marshalData[0]) if err != nil { return nil, err } // TODO: data needs to stay in scope until the source func is gone. c = C._g_closure_new_with_data((C.gpointer)(p)) } // Associate the GClosure with rf. rf will be looked up in this // map by the closure when the closure runs. closures.Lock() closures.m[c] = rf closures.Unlock() return c, nil }