package muesli import "fmt" // Door is an example of how to wrap a custom type in Muesli. type Door struct { *BasicObject name string locked bool opened bool } var _ Value = &Door{} const DoorType = TypeValue("Door") func (door * Door) String() string { return fmt.Sprintf("Door: %s %v %v", door.name, door.locked, door.opened) } func (*Door) Type() TypeValue { return DoorType } func (from * Door) Convert(to interface{}) error { switch toPtr := to.(type) { case **Door: (*toPtr) = from case *Door: (*toPtr) = *from case *Value: (*toPtr) = from default: return NewErrorValuef("Cannot convert DoorValue value %v to %v", from, to) } return nil } func door(vm *VM, val ...Value) [] Value { var name string var locked bool _, err := ParseOptArgs(val, 1, &name, &locked) if err != nil { return Fail(err) } d := &Door{name: name, locked: locked, opened:false} d.BasicObject = NewBasicObject(d, nil) d.Getter("name", func() Value { return StringValue(d.name) }) d.Getter("locked", func() Value { return BoolValue(d.locked) }) d.Getter("opened", func() Value { return BoolValue(d.opened) }) d.Method("open", func(...Value) []Value { d.Open() return Ok(d) }) return Ok(d) } func (door * Door) Open() { door.opened = true } func openDoor(vm *VM, val ...Value) [] Value { var door *Door _, err := ParseArgs(val, &door) if err != nil { return Fail(err) } if door == nil { return Fail(NewErrorValuef("Door may not be nil.")) } door.Open() return Ok(door) } func nameDoor(vm *VM, val ...Value) [] Value { var door *Door var name string _, err := ParseArgs(val, &door, &name) if err != nil { return Fail(err) } if door == nil { return Fail(NewErrorValuef("Door may not be nil.")) } if name == "" { return Fail(NewErrorValuef("Name may not be empty.")) } door.name = name return Ok(door) } func RegisterDoor(vm * VM) { vm.RegisterBuiltin("door", door) vm.RegisterBuiltin("openDoor", openDoor).Takes(DoorType).Returns(DoorType) vm.RegisterBuiltin("nameDoor", nameDoor).Takes(DoorType).Returns(DoorType) vm.Register("Door", DoorType) vm.AddOverloadByName("open", "openDoor", 0) vm.AddOverloads("name", Over("nameDoor", 0, DoorType)) }