mirror of
https://github.com/ziutek/glib.git
synced 2025-10-05 15:06:57 +08:00
Widac jakis sens
This commit is contained in:
5
Makefile
5
Makefile
@@ -1,7 +1,6 @@
|
|||||||
include $(GOROOT)/src/Make.inc
|
include $(GOROOT)/src/Make.inc
|
||||||
|
|
||||||
TARG=gobject
|
TARG = glib
|
||||||
CGOFILES=\
|
CGOFILES = pkgconfig.go type.go value.go object.go closure.go signal.go
|
||||||
gobject.go\
|
|
||||||
|
|
||||||
include $(GOROOT)/src/Make.pkg
|
include $(GOROOT)/src/Make.pkg
|
||||||
|
88
closure.go
Normal file
88
closure.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "closure.h"
|
||||||
|
|
||||||
|
static inline GoClosure* go_closure_ref(GoClosure* c) {
|
||||||
|
return (GoClosure*) g_closure_ref((GClosure*) c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void go_closure_unref(GoClosure* c) {
|
||||||
|
g_closure_unref((GClosure*) c);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GClosure *cl;
|
||||||
|
GValue *ret_val;
|
||||||
|
guint n_param;
|
||||||
|
const GValue *params;
|
||||||
|
gpointer ih;
|
||||||
|
gpointer data;
|
||||||
|
} MarshalParams;
|
||||||
|
|
||||||
|
extern void go_marshal(gpointer mp);
|
||||||
|
|
||||||
|
static void closure_marshal(GClosure* cl, GValue* ret_val, guint n_param,
|
||||||
|
const GValue* params, gpointer ih, gpointer data) {
|
||||||
|
MarshalParams mp = {cl, ret_val, n_param, params, ih, data};
|
||||||
|
go_marshal(&mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GoClosure* go_closure_new(void* cb) {
|
||||||
|
GoClosure *cl = (GoClosure*) g_closure_new_simple(sizeof (GoClosure), NULL);
|
||||||
|
cl->cb = cb;
|
||||||
|
g_closure_set_marshal((GClosure *) cl, closure_marshal);
|
||||||
|
return cl;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Closure struct {
|
||||||
|
cl *C.GoClosure
|
||||||
|
cb *reflect.Value // Callback function
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClosure(cb_func interface{}) (c *Closure) {
|
||||||
|
cb := reflect.ValueOf(cb_func)
|
||||||
|
if cb.Kind() != reflect.Func {
|
||||||
|
panic("cb_func is not a function")
|
||||||
|
}
|
||||||
|
c = &Closure{C.go_closure_new(unsafe.Pointer(&cb)), &cb}
|
||||||
|
runtime.SetFinalizer(c, (*Closure).destroy)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Closure) Ref() *Closure {
|
||||||
|
if c.cl == nil {
|
||||||
|
panic("Ref on nil closure")
|
||||||
|
}
|
||||||
|
return &Closure{C.go_closure_ref(c.cl), c.cb}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Closure) Unref() {
|
||||||
|
if c.cl == nil {
|
||||||
|
panic("Unref on nil closure")
|
||||||
|
}
|
||||||
|
C.go_closure_unref(c.cl)
|
||||||
|
c.cl = nil
|
||||||
|
c.cb = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Closure) destroy() {
|
||||||
|
if c.cl != nil {
|
||||||
|
C.go_closure_unref(c.cl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//export go_marshal
|
||||||
|
func marshal(mp unsafe.Pointer) {
|
||||||
|
//p := (*C.MarshalParams)(mp)
|
||||||
|
fmt.Println("Doszedl!")
|
||||||
|
}
|
6
closure.h
Normal file
6
closure.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GClosure cl;
|
||||||
|
gpointer cb;
|
||||||
|
} GoClosure;
|
29
glib_test.go
Normal file
29
glib_test.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValue(t *testing.T) {
|
||||||
|
v1 := uint64(0xdeadbeaf)
|
||||||
|
a := ValueOf(v1)
|
||||||
|
b := NewValueInit(TYPE_UINT64)
|
||||||
|
a.Copy(b)
|
||||||
|
t.Logf("a = %s(%s), b = %s(%s)", a.Type(), a, b.Type(), b)
|
||||||
|
if b.Get().(uint64) != v1 {
|
||||||
|
t.Error("TYPE_UINT64")
|
||||||
|
}
|
||||||
|
v2 := -1
|
||||||
|
a = ValueOf(v2)
|
||||||
|
b = NewValueInit(TYPE_INT)
|
||||||
|
a.Copy(b)
|
||||||
|
t.Logf("a = %s(%s), b = %s(%s)", a.Type(), a, b.Type(), b)
|
||||||
|
if b.Get() != v2 {
|
||||||
|
t.Error("TYPE_INT")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignal(t *testing.T) {
|
||||||
|
s := NewSignal("bla", TYPE_NONE, TYPE_GO_INT)
|
||||||
|
t.Logf("Signal: %s", s)
|
||||||
|
}
|
91
gobject.go
91
gobject.go
@@ -1,91 +0,0 @@
|
|||||||
package glib
|
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo pkg-config: glib-2.0 gobject-2.0
|
|
||||||
|
|
||||||
#include <glib-object.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A numerical value which represents the unique identifier of a registered type
|
|
||||||
type Type C.GType
|
|
||||||
|
|
||||||
const (
|
|
||||||
TYPE_INVALID = Type(C.G_TYPE_INVALID)
|
|
||||||
TYPE_NONE = Type(C.G_TYPE_NONE)
|
|
||||||
TYPE_INTERFACE = Type(C.G_TYPE_INTERFACE)
|
|
||||||
TYPE_CHAR = Type(C.G_TYPE_CHAR)
|
|
||||||
TYPE_UCHAR = Type(C.G_TYPE_UCHAR)
|
|
||||||
TYPE_BOOLEAN = Type(C.G_TYPE_BOOLEAN)
|
|
||||||
TYPE_INT = Type(C.G_TYPE_INT)
|
|
||||||
TYPE_UINT = Type(C.G_TYPE_UINT)
|
|
||||||
TYPE_LONG = Type(C.G_TYPE_LONG)
|
|
||||||
TYPE_ULONG = Type(C.G_TYPE_ULONG)
|
|
||||||
TYPE_INT64 = Type(C.G_TYPE_INT64)
|
|
||||||
TYPE_UINT64 = Type(C.G_TYPE_UINT64)
|
|
||||||
TYPE_ENUM = Type(C.G_TYPE_ENUM)
|
|
||||||
TYPE_FLAGS = Type(C.G_TYPE_FLAGS)
|
|
||||||
TYPE_FLOAT = Type(C.G_TYPE_FLOAT)
|
|
||||||
TYPE_DOUBLE = Type(C.G_TYPE_DOUBLE)
|
|
||||||
TYPE_STRING = Type(C.G_TYPE_STRING)
|
|
||||||
TYPE_POINTER = Type(C.G_TYPE_POINTER)
|
|
||||||
TYPE_BOXED = Type(C.G_TYPE_BOXED)
|
|
||||||
TYPE_PARAM = Type(C.G_TYPE_PARAM)
|
|
||||||
TYPE_OBJECT = Type(C.G_TYPE_OBJECT)
|
|
||||||
TYPE_VARIANT = Type(C.G_TYPE_VARIANT)
|
|
||||||
)
|
|
||||||
|
|
||||||
var TYPE_GTYPE = Type(C.g_gtype_get_type())
|
|
||||||
|
|
||||||
|
|
||||||
type Object struct {
|
|
||||||
obj *C.GObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Object) Ref() Object {
|
|
||||||
if o.obj == nil {
|
|
||||||
panic("Ref on nil object")
|
|
||||||
}
|
|
||||||
return Object{(*C.GObject)(C.g_object_ref(C.gpointer(o.obj)))}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Object) Unref() {
|
|
||||||
if o.obj == nil {
|
|
||||||
panic("Unref on nil object")
|
|
||||||
}
|
|
||||||
C.g_object_unref(C.gpointer(o.obj))
|
|
||||||
o.obj = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Object) destroy() {
|
|
||||||
if o.obj != nil {
|
|
||||||
C.g_object_unref(C.gpointer(o.obj))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func MapGObject(obj *C.GObject) (o Object) {
|
|
||||||
o.obj = obj
|
|
||||||
runtime.SetFinalizer(o, (*Object).destroy)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func MapGPointer(p C.gpointer) (o Object) {
|
|
||||||
return MapGObject((*C.GObject)(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewObject(t Type) Object {
|
|
||||||
return MapGPointer(C.g_object_newv(C.GType(t), 0, nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Object) Emit(name string, ...interface{}) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
C.g_thread_init(nil)
|
|
||||||
C.g_type_init()
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
package gobject
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAll(t *testing.T) {
|
|
||||||
Print()
|
|
||||||
time.Sleep(100e9)
|
|
||||||
}
|
|
92
object.go
Normal file
92
object.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "closure.h"
|
||||||
|
|
||||||
|
static inline
|
||||||
|
gulong go_signal_connect(GObject* inst, guint sig, GoClosure* cl) {
|
||||||
|
return g_signal_connect_closure_by_id(
|
||||||
|
(gpointer) inst,
|
||||||
|
sig,
|
||||||
|
0,
|
||||||
|
(GClosure*) cl,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void go_signal_emit(const GValue *inst_and_params, guint sig, GValue *ret) {
|
||||||
|
return g_signal_emitv(
|
||||||
|
inst_and_params,
|
||||||
|
sig,
|
||||||
|
0,
|
||||||
|
ret
|
||||||
|
);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SigHandlerId C.gulong
|
||||||
|
|
||||||
|
type Object struct {
|
||||||
|
obj *C.GObject
|
||||||
|
cls map[SigHandlerId]*Closure
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) Ref() *Object {
|
||||||
|
if o.obj == nil {
|
||||||
|
panic("Ref on nil object")
|
||||||
|
}
|
||||||
|
return &Object{(*C.GObject)(C.g_object_ref(C.gpointer(o.obj))), o.cls}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) Unref() {
|
||||||
|
if o.obj == nil {
|
||||||
|
panic("Unref on nil object")
|
||||||
|
}
|
||||||
|
C.g_object_unref(C.gpointer(o.obj))
|
||||||
|
o.obj = nil
|
||||||
|
o.cls = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) destroy() {
|
||||||
|
if o.obj != nil {
|
||||||
|
C.g_object_unref(C.gpointer(o.obj))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MapGObject(obj *C.GObject) (o *Object) {
|
||||||
|
o = &Object{obj, make(map[SigHandlerId]*Closure)}
|
||||||
|
runtime.SetFinalizer(o, (*Object).destroy)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func MapGPointer(p C.gpointer) (o *Object) {
|
||||||
|
return MapGObject((*C.GObject)(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObject(t Type) *Object {
|
||||||
|
return MapGPointer(C.g_object_newv(C.GType(t), 0, nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) Connect(sig Signal, cb_func interface{}) {
|
||||||
|
c := NewClosure(cb_func)
|
||||||
|
h := SigHandlerId(C.go_signal_connect(o.obj, C.guint(sig), c.cl))
|
||||||
|
o.cls[h] = c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) Emit(sig Signal, args ...interface{}) interface{} {
|
||||||
|
prms := make([]Value, len(args) + 1)
|
||||||
|
prms[0] = *ValueOf(o.obj)
|
||||||
|
for i, a := range args {
|
||||||
|
prms[i+1] = *ValueOf(a)
|
||||||
|
}
|
||||||
|
ret := NewValue()
|
||||||
|
C.go_signal_emit((*C.GValue)(&prms[0]), C.guint(sig), (*C.GValue)(ret))
|
||||||
|
return ret.Get()
|
||||||
|
}
|
4
pkgconfig.go
Normal file
4
pkgconfig.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
//#cgo pkg-config: glib-2.0 gobject-2.0
|
||||||
|
import "C"
|
42
signal.go
Normal file
42
signal.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
static inline guint go_signal_new(char* name, GType ot, guint ni, GType* it) {
|
||||||
|
return g_signal_newv(
|
||||||
|
name,
|
||||||
|
G_TYPE_OBJECT,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
ot,
|
||||||
|
ni,
|
||||||
|
it
|
||||||
|
);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Signal C.guint
|
||||||
|
|
||||||
|
func NewSignal(name string, ot Type, it ...Type) Signal {
|
||||||
|
sig_name := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(sig_name))
|
||||||
|
var cit *C.GType
|
||||||
|
if len(it) > 0 {
|
||||||
|
cit = (*C.GType)(&it[0])
|
||||||
|
}
|
||||||
|
return Signal(C.go_signal_new(sig_name, C.GType(ot), C.guint(len(it)), cit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Signal) String() string {
|
||||||
|
return C.GoString((*C.char)(C.g_signal_name(C.guint(s))))
|
||||||
|
}
|
120
type.go
Normal file
120
type.go
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#define _GINT_SIZE sizeof(gint)
|
||||||
|
#define _GLONG_SIZE sizeof(glong)
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A numerical value which represents the unique identifier of a registered type
|
||||||
|
type Type C.GType
|
||||||
|
|
||||||
|
const (
|
||||||
|
TYPE_INVALID = Type(C.G_TYPE_INVALID)
|
||||||
|
TYPE_NONE = Type(C.G_TYPE_NONE)
|
||||||
|
TYPE_INTERFACE = Type(C.G_TYPE_INTERFACE)
|
||||||
|
TYPE_CHAR = Type(C.G_TYPE_CHAR)
|
||||||
|
TYPE_UCHAR = Type(C.G_TYPE_UCHAR)
|
||||||
|
TYPE_BOOLEAN = Type(C.G_TYPE_BOOLEAN)
|
||||||
|
TYPE_INT = Type(C.G_TYPE_INT)
|
||||||
|
TYPE_UINT = Type(C.G_TYPE_UINT)
|
||||||
|
TYPE_LONG = Type(C.G_TYPE_LONG)
|
||||||
|
TYPE_ULONG = Type(C.G_TYPE_ULONG)
|
||||||
|
TYPE_INT64 = Type(C.G_TYPE_INT64)
|
||||||
|
TYPE_UINT64 = Type(C.G_TYPE_UINT64)
|
||||||
|
TYPE_ENUM = Type(C.G_TYPE_ENUM)
|
||||||
|
TYPE_FLAGS = Type(C.G_TYPE_FLAGS)
|
||||||
|
TYPE_FLOAT = Type(C.G_TYPE_FLOAT)
|
||||||
|
TYPE_DOUBLE = Type(C.G_TYPE_DOUBLE)
|
||||||
|
TYPE_STRING = Type(C.G_TYPE_STRING)
|
||||||
|
TYPE_POINTER = Type(C.G_TYPE_POINTER)
|
||||||
|
TYPE_BOXED = Type(C.G_TYPE_BOXED)
|
||||||
|
TYPE_PARAM = Type(C.G_TYPE_PARAM)
|
||||||
|
TYPE_OBJECT = Type(C.G_TYPE_OBJECT)
|
||||||
|
TYPE_VARIANT = Type(C.G_TYPE_VARIANT)
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
TYPE_GTYPE Type
|
||||||
|
TYPE_GO_INT Type
|
||||||
|
TYPE_GO_UINT Type
|
||||||
|
TYPE_GO_INT32 Type
|
||||||
|
TYPE_GO_UINT32 Type
|
||||||
|
)
|
||||||
|
|
||||||
|
// Returns the Type of the value in the interface{}.
|
||||||
|
func TypeOf(i interface{}) Type {
|
||||||
|
switch i.(type) {
|
||||||
|
case string:
|
||||||
|
return TYPE_STRING
|
||||||
|
case int:
|
||||||
|
return TYPE_GO_INT
|
||||||
|
case uint:
|
||||||
|
return TYPE_GO_UINT
|
||||||
|
case int8:
|
||||||
|
return TYPE_CHAR
|
||||||
|
case uint8:
|
||||||
|
return TYPE_UCHAR
|
||||||
|
case int32:
|
||||||
|
return TYPE_GO_INT32
|
||||||
|
case uint32:
|
||||||
|
return TYPE_GO_UINT32
|
||||||
|
case int64:
|
||||||
|
return TYPE_INT64
|
||||||
|
case uint64:
|
||||||
|
return TYPE_UINT64
|
||||||
|
case bool:
|
||||||
|
return TYPE_BOOLEAN
|
||||||
|
case float32:
|
||||||
|
return TYPE_FLOAT
|
||||||
|
case float64:
|
||||||
|
return TYPE_DOUBLE
|
||||||
|
case unsafe.Pointer:
|
||||||
|
return TYPE_POINTER
|
||||||
|
case *Object:
|
||||||
|
return TYPE_OBJECT
|
||||||
|
case Type:
|
||||||
|
return TYPE_GTYPE
|
||||||
|
}
|
||||||
|
return TYPE_INVALID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Type) String() string {
|
||||||
|
return C.GoString((*C.char)(C.g_type_name(C.GType(t))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
C.g_thread_init(nil)
|
||||||
|
C.g_type_init()
|
||||||
|
TYPE_GTYPE = Type(C.g_gtype_get_type())
|
||||||
|
switch strconv.IntSize / 8 {
|
||||||
|
case uint(C._GINT_SIZE):
|
||||||
|
TYPE_GO_INT = TYPE_INT
|
||||||
|
TYPE_GO_UINT = TYPE_UINT
|
||||||
|
case uint(C._GLONG_SIZE):
|
||||||
|
TYPE_GO_INT = TYPE_LONG
|
||||||
|
TYPE_GO_UINT = TYPE_ULONG
|
||||||
|
case 64:
|
||||||
|
TYPE_GO_INT = TYPE_INT64
|
||||||
|
TYPE_GO_UINT = TYPE_UINT64
|
||||||
|
default:
|
||||||
|
panic("Unexpectd size of 'int'")
|
||||||
|
}
|
||||||
|
switch C.uint(4) {
|
||||||
|
case C._GINT_SIZE:
|
||||||
|
TYPE_GO_INT32 = TYPE_INT
|
||||||
|
TYPE_GO_UINT32 = TYPE_UINT
|
||||||
|
case C._GLONG_SIZE:
|
||||||
|
TYPE_GO_INT32 = TYPE_LONG
|
||||||
|
TYPE_GO_UINT32 = TYPE_ULONG
|
||||||
|
default:
|
||||||
|
panic("Neither gint nor glong are 32 bit numbers")
|
||||||
|
}
|
||||||
|
}
|
172
value.go
Normal file
172
value.go
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
package glib
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <glib-object.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"runtime"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An opaque structure used to hold different types of values.
|
||||||
|
type Value C.GValue
|
||||||
|
|
||||||
|
// Returns v's type.
|
||||||
|
func (v *Value) Type() Type {
|
||||||
|
return Type(v.g_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set value to i
|
||||||
|
func (v *Value) Set(i interface{}) {
|
||||||
|
switch x := i.(type) {
|
||||||
|
case string:
|
||||||
|
C.g_value_set_static_string(
|
||||||
|
(*C.GValue)(v),
|
||||||
|
(*C.gchar)(C.CString(x)),
|
||||||
|
)
|
||||||
|
case int:
|
||||||
|
if TYPE_GO_INT == TYPE_INT {
|
||||||
|
C.g_value_set_int((*C.GValue)(v), C.gint(x))
|
||||||
|
} else {
|
||||||
|
C.g_value_set_long((*C.GValue)(v), C.glong(x))
|
||||||
|
}
|
||||||
|
case uint:
|
||||||
|
if TYPE_GO_INT == TYPE_INT {
|
||||||
|
C.g_value_set_uint((*C.GValue)(v), C.guint(x))
|
||||||
|
} else {
|
||||||
|
C.g_value_set_ulong((*C.GValue)(v), C.gulong(x))
|
||||||
|
}
|
||||||
|
case int8:
|
||||||
|
C.g_value_set_char((*C.GValue)(v), C.gchar(x))
|
||||||
|
case uint8:
|
||||||
|
C.g_value_set_uchar((*C.GValue)(v), C.guchar(x))
|
||||||
|
case int32:
|
||||||
|
if TYPE_GO_INT32 == TYPE_INT {
|
||||||
|
C.g_value_set_int((*C.GValue)(v), C.gint(x))
|
||||||
|
} else {
|
||||||
|
C.g_value_set_long((*C.GValue)(v), C.glong(x))
|
||||||
|
}
|
||||||
|
case uint32:
|
||||||
|
if TYPE_GO_INT32 == TYPE_INT {
|
||||||
|
C.g_value_set_uint((*C.GValue)(v), C.guint(x))
|
||||||
|
} else {
|
||||||
|
C.g_value_set_ulong((*C.GValue)(v), C.gulong(x))
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
C.g_value_set_int64((*C.GValue)(v), C.gint64(x))
|
||||||
|
case uint64:
|
||||||
|
C.g_value_set_uint64((*C.GValue)(v), C.guint64(x))
|
||||||
|
case bool:
|
||||||
|
if x {
|
||||||
|
C.g_value_set_boolean((*C.GValue)(v), C.gboolean(1))
|
||||||
|
} else {
|
||||||
|
C.g_value_set_boolean((*C.GValue)(v), C.gboolean(0))
|
||||||
|
}
|
||||||
|
case float32:
|
||||||
|
C.g_value_set_float((*C.GValue)(v), C.gfloat(x))
|
||||||
|
case float64:
|
||||||
|
C.g_value_set_double((*C.GValue)(v), C.gdouble(x))
|
||||||
|
case unsafe.Pointer:
|
||||||
|
C.g_value_set_pointer((*C.GValue)(v), C.gpointer(x))
|
||||||
|
case *Object:
|
||||||
|
C.g_value_set_object((*C.GValue)(v), C.gpointer(x.obj))
|
||||||
|
case nil:
|
||||||
|
C.g_value_reset((*C.GValue)(v))
|
||||||
|
default:
|
||||||
|
panic("Unknown type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns new uninitialized value
|
||||||
|
func NewValue() *Value {
|
||||||
|
v := new(Value)
|
||||||
|
runtime.SetFinalizer(v, (*Value).Unset)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes value with the default value of type.
|
||||||
|
func (v *Value) Init(t Type) {
|
||||||
|
C.g_value_init((*C.GValue)(v), C.GType(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clears the current value in value and "unsets" the type,
|
||||||
|
func (v *Value) Unset() {
|
||||||
|
C.g_value_unset((*C.GValue)(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns new initializes value
|
||||||
|
func NewValueInit(t Type) *Value {
|
||||||
|
v := NewValue()
|
||||||
|
v.Init(t)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a new Value initialized to the value stored in the interface i.
|
||||||
|
func ValueOf(i interface{}) *Value {
|
||||||
|
v := NewValueInit(TypeOf(i))
|
||||||
|
v.Set(i)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copies the value into dst.
|
||||||
|
func (v *Value) Copy(dst *Value) {
|
||||||
|
C.g_value_copy((*C.GValue)(v), (*C.GValue)(dst))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Value) Get() interface{} {
|
||||||
|
switch Type((*C.GValue)(v).g_type) {
|
||||||
|
case TYPE_STRING:
|
||||||
|
return C.GoString((*C.char)(C.g_value_get_string((*C.GValue)(v))))
|
||||||
|
case TYPE_GO_INT:
|
||||||
|
if TYPE_GO_INT == TYPE_INT {
|
||||||
|
return int(C.g_value_get_int((*C.GValue)(v)))
|
||||||
|
} else {
|
||||||
|
return int(C.g_value_get_long((*C.GValue)(v)))
|
||||||
|
}
|
||||||
|
case TYPE_GO_UINT:
|
||||||
|
if TYPE_GO_INT == TYPE_INT {
|
||||||
|
return uint(C.g_value_get_uint((*C.GValue)(v)))
|
||||||
|
} else {
|
||||||
|
return uint(C.g_value_get_ulong((*C.GValue)(v)))
|
||||||
|
}
|
||||||
|
case TYPE_CHAR:
|
||||||
|
return int8(C.g_value_get_char((*C.GValue)(v)))
|
||||||
|
case TYPE_UCHAR:
|
||||||
|
return uint8(C.g_value_get_uchar((*C.GValue)(v)))
|
||||||
|
case TYPE_GO_INT32:
|
||||||
|
if TYPE_GO_INT32 == TYPE_INT {
|
||||||
|
return int32(C.g_value_get_int((*C.GValue)(v)))
|
||||||
|
} else {
|
||||||
|
return int32(C.g_value_get_long((*C.GValue)(v)))
|
||||||
|
}
|
||||||
|
case TYPE_GO_UINT32:
|
||||||
|
if TYPE_GO_INT32 == TYPE_INT {
|
||||||
|
return uint32(C.g_value_get_uint((*C.GValue)(v)))
|
||||||
|
} else {
|
||||||
|
return uint32(C.g_value_get_ulong((*C.GValue)(v)))
|
||||||
|
}
|
||||||
|
case TYPE_INT64:
|
||||||
|
return int64(C.g_value_get_int64((*C.GValue)(v)))
|
||||||
|
case TYPE_UINT64:
|
||||||
|
return uint64(C.g_value_get_uint64((*C.GValue)(v)))
|
||||||
|
case TYPE_BOOLEAN:
|
||||||
|
return (C.g_value_get_boolean((*C.GValue)(v)) != C.gboolean(0))
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
return float32(C.g_value_get_float((*C.GValue)(v)))
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
return float64(C.g_value_get_double((*C.GValue)(v)))
|
||||||
|
case TYPE_POINTER:
|
||||||
|
return unsafe.Pointer(C.g_value_get_pointer((*C.GValue)(v)))
|
||||||
|
case TYPE_OBJECT:
|
||||||
|
return MapGPointer(C.g_value_get_object((*C.GValue)(v)))
|
||||||
|
}
|
||||||
|
// TODO - shoulda work with more GLIB types
|
||||||
|
panic("Can't represent value in Go type system.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Value) String() string {
|
||||||
|
return fmt.Sprint(v.Get())
|
||||||
|
}
|
Reference in New Issue
Block a user