forked from mitchellh/go-mruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
class.go
88 lines (71 loc) · 2.06 KB
/
class.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package mruby
import "unsafe"
// #include <stdlib.h>
// #include "gomruby.h"
import "C"
// Class is a class in mruby. To obtain a Class, use DefineClass or
// one of the variants on the Mrb structure.
type Class struct {
class *C.struct_RClass
mrb *Mrb
}
// DefineClassMethod defines a class-level method on the given class.
func (c *Class) DefineClassMethod(name string, cb Func, as ArgSpec) {
insertMethod(c.mrb.state, c.class.c, name, cb)
cs := C.CString(name)
defer C.free(unsafe.Pointer(cs))
C.mrb_define_class_method(
c.mrb.state,
c.class,
cs,
C._go_mrb_func_t(),
C.mrb_aspec(as))
}
// DefineConst defines a constant within this class.
func (c *Class) DefineConst(name string, value Value) {
cs := C.CString(name)
defer C.free(unsafe.Pointer(cs))
C.mrb_define_const(
c.mrb.state, c.class, cs, value.MrbValue(c.mrb).value)
}
// DefineMethod defines an instance method on the class.
func (c *Class) DefineMethod(name string, cb Func, as ArgSpec) {
insertMethod(c.mrb.state, c.class, name, cb)
cs := C.CString(name)
defer C.free(unsafe.Pointer(cs))
C.mrb_define_method(
c.mrb.state,
c.class,
cs,
C._go_mrb_func_t(),
C.mrb_aspec(as))
}
// MrbValue returns a *Value for this Class. *Values are sometimes required
// as arguments where classes should be valid.
func (c *Class) MrbValue(m *Mrb) *MrbValue {
return newValue(c.mrb.state, C.mrb_obj_value(unsafe.Pointer(c.class)))
}
// New instantiates the class with the given args.
func (c *Class) New(args ...Value) (*MrbValue, error) {
var argv []C.mrb_value
var argvPtr *C.mrb_value
if len(args) > 0 {
// Make the raw byte slice to hold our arguments we'll pass to C
argv = make([]C.mrb_value, len(args))
for i, arg := range args {
argv[i] = arg.MrbValue(c.mrb).value
}
argvPtr = &argv[0]
}
result := C.mrb_obj_new(c.mrb.state, c.class, C.mrb_int(len(argv)), argvPtr)
if exc := checkException(c.mrb.state); exc != nil {
return nil, exc
}
return newValue(c.mrb.state, result), nil
}
func newClass(mrb *Mrb, c *C.struct_RClass) *Class {
return &Class{
class: c,
mrb: mrb,
}
}