door.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package muesli
  2. import "fmt"
  3. // Door is an example of how to wrap a custom type in Muesli.
  4. type Door struct {
  5. RedispatchCallable
  6. name string
  7. locked bool
  8. opened bool
  9. }
  10. var _ Callable = &Door{}
  11. const DoorType = TypeValue("Door")
  12. func (door * Door) String() string {
  13. return fmt.Sprintf("Door: %s %v %v", door.name, door.locked, door.opened)
  14. }
  15. func (*Door) Type() TypeValue {
  16. return DoorType
  17. }
  18. func (from * Door) Convert(to interface{}) error {
  19. switch toPtr := to.(type) {
  20. case **Door:
  21. (*toPtr) = from
  22. case *Door:
  23. (*toPtr) = *from
  24. case *Value:
  25. (*toPtr) = from
  26. default:
  27. return NewErrorValuef("Cannot convert DoorValue value %v to %v", from, to)
  28. }
  29. return nil
  30. }
  31. func door(vm *VM, val ...Value) [] Value {
  32. var name string
  33. var locked bool
  34. _, err := ParseOptArgs(val, 1, &name, &locked)
  35. if err != nil {
  36. return Fail(err)
  37. }
  38. d := &Door{name: name, locked: locked, opened:false}
  39. d.RedispatchCallable = NewRedispatchCallable("Door", d)
  40. return Ok(d)
  41. }
  42. func (door * Door) Open() {
  43. door.opened = true
  44. }
  45. func openDoor(vm *VM, val ...Value) [] Value {
  46. var door *Door
  47. _, err := ParseArgs(val, &door)
  48. if err != nil {
  49. return Fail(err)
  50. }
  51. if door == nil {
  52. return Fail(NewErrorValuef("Door may not be nil."))
  53. }
  54. door.Open()
  55. return Ok(door)
  56. }
  57. func nameDoor(vm *VM, val ...Value) [] Value {
  58. var door *Door
  59. var name string
  60. _, err := ParseArgs(val, &door, &name)
  61. if err != nil {
  62. return Fail(err)
  63. }
  64. if door == nil {
  65. return Fail(NewErrorValuef("Door may not be nil."))
  66. }
  67. if name == "" {
  68. return Fail(NewErrorValuef("Name may not be empty."))
  69. }
  70. door.name = name
  71. return Ok(door)
  72. }
  73. func RegisterDoor(vm * VM) {
  74. vm.RegisterBuiltin("door", door)
  75. vm.RegisterBuiltin("openDoor", openDoor).Takes(DoorType).Returns(DoorType)
  76. vm.RegisterBuiltin("nameDoor", nameDoor).Takes(DoorType).Returns(DoorType)
  77. vm.Register("Door", DoorType)
  78. vm.AddOverloadByName("open", "openDoor", 0)
  79. vm.AddOverloads("name", Over("nameDoor", 0, DoorType))
  80. }