123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- package al
- /*
- #cgo pkg-config: allegro-5
- #cgo CFLAGS: -I/usr/local/include
- #cgo linux LDFLAGS: -lc_nonshared
- #include <stdlib.h>
- #include <allegro5/allegro.h>
- #include <allegro5/events.h>
- #include "helpers.h"
- */
- import "C"
- import "unsafe"
- import "runtime"
- // EventUnion Type, not to avoid complications.
- // type EVENT_TYPE C.ALLEGRO_EVENT_TYPE
- // EventUnion Type constants
- const (
- EVENT_JOYSTICK_AXIS = C.ALLEGRO_EVENT_JOYSTICK_AXIS
- EVENT_JOYSTICK_BUTTON_DOWN = C.ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN
- EVENT_JOYSTICK_BUTTON_UP = C.ALLEGRO_EVENT_JOYSTICK_BUTTON_UP
- EVENT_JOYSTICK_CONFIGURATION = C.ALLEGRO_EVENT_JOYSTICK_CONFIGURATION
- EVENT_KEY_DOWN = C.ALLEGRO_EVENT_KEY_DOWN
- EVENT_KEY_CHAR = C.ALLEGRO_EVENT_KEY_CHAR
- EVENT_KEY_UP = C.ALLEGRO_EVENT_KEY_UP
- EVENT_MOUSE_AXES = C.ALLEGRO_EVENT_MOUSE_AXES
- EVENT_MOUSE_BUTTON_DOWN = C.ALLEGRO_EVENT_MOUSE_BUTTON_DOWN
- EVENT_MOUSE_BUTTON_UP = C.ALLEGRO_EVENT_MOUSE_BUTTON_UP
- EVENT_MOUSE_ENTER_DISPLAY = C.ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY
- EVENT_MOUSE_LEAVE_DISPLAY = C.ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY
- EVENT_MOUSE_WARPED = C.ALLEGRO_EVENT_MOUSE_WARPED
- EVENT_TIMER = C.ALLEGRO_EVENT_TIMER
- EVENT_DISPLAY_EXPOSE = C.ALLEGRO_EVENT_DISPLAY_EXPOSE
- EVENT_DISPLAY_RESIZE = C.ALLEGRO_EVENT_DISPLAY_RESIZE
- EVENT_DISPLAY_CLOSE = C.ALLEGRO_EVENT_DISPLAY_CLOSE
- EVENT_DISPLAY_LOST = C.ALLEGRO_EVENT_DISPLAY_LOST
- EVENT_DISPLAY_FOUND = C.ALLEGRO_EVENT_DISPLAY_FOUND
- EVENT_DISPLAY_SWITCH_IN = C.ALLEGRO_EVENT_DISPLAY_SWITCH_IN
- EVENT_DISPLAY_SWITCH_OUT = C.ALLEGRO_EVENT_DISPLAY_SWITCH_OUT
- EVENT_DISPLAY_ORIENTATION = C.ALLEGRO_EVENT_DISPLAY_ORIENTATION
- EVENT_TOUCH_BEGIN = C.ALLEGRO_EVENT_TOUCH_BEGIN
- EVENT_TOUCH_END = C.ALLEGRO_EVENT_TOUCH_END
- EVENT_TOUCH_MOVE = C.ALLEGRO_EVENT_TOUCH_MOVE
- EVENT_TOUCH_CANCEL = C.ALLEGRO_EVENT_TOUCH_CANCEL
- EVENT_DISPLAY_CONNECTED = C.ALLEGRO_EVENT_DISPLAY_CONNECTED
- EVENT_DISPLAY_DISCONNECTED = C.ALLEGRO_EVENT_DISPLAY_DISCONNECTED
- )
- func EVENT_TYPE_IS_USER(t int) bool {
- return ((t) >= 512)
- }
- func GET_EVENT_TYPE(a, b, c, d int) int {
- return AL_ID(a, b, c, d)
- }
- func getAnyEvenTimestamp(any *C.ALLEGRO_ANY_EVENT) float64 {
- return float64(any.timestamp)
- }
- // Wrapper interface for different event sources
- type EventSourcer interface {
- EventSource() * EventSource
- }
- func (disp * Display) EventSource() * EventSource {
- return (*EventSource)(unsafe.Pointer(disp))
- }
- func (joy * Joystick) EventSource() * EventSource {
- return (*EventSource)(unsafe.Pointer(joy))
- }
- func (key * Keyboard) EventSource() * EventSource {
- return (*EventSource)(unsafe.Pointer(key))
- }
- func (mouse * Mouse) EventSource() * EventSource {
- return (*EventSource)(unsafe.Pointer(mouse))
- }
- func (touch * TouchInput) EventSource() * EventSource {
- return (*EventSource)(unsafe.Pointer(touch))
- }
- func (timer * Timer) EventSource() * EventSource {
- return (*EventSource)(unsafe.Pointer(timer))
- }
- func (es * EventSource) EventSource() * EventSource {
- return es
- }
-
- // Event sources that emit events.
- type EventSource C.ALLEGRO_EVENT_SOURCE
- // Wraps an event source pointer but sets no finalizer (not needed anyway)
- func wrapEventSourceRaw(ptr *C.ALLEGRO_EVENT_SOURCE) *EventSource {
- return (*EventSource)(ptr)
- }
- // Converts wrapper EventUnion source pointer to C Allegro event source pointer
- func (self *EventSource) toC() *C.ALLEGRO_EVENT_SOURCE {
- return (*C.ALLEGRO_EVENT_SOURCE)(self)
- }
- // Events that the event system emits.
- type EventUnion C.ALLEGRO_EVENT
- // use an EventUnion interface to wrap the
- // C union's members in
- type Event interface {
- Type() int
- Source() EventSourcer
- Timestamp() float64
- }
- type AnyEvent C.ALLEGRO_ANY_EVENT
- type DisplayEvent C.ALLEGRO_DISPLAY_EVENT
- type JoystickEvent C.ALLEGRO_JOYSTICK_EVENT
- type KeyboardEvent C.ALLEGRO_KEYBOARD_EVENT
- type MouseEvent C.ALLEGRO_MOUSE_EVENT
- type TimerEvent C.ALLEGRO_TIMER_EVENT
- type TouchEvent C.ALLEGRO_TOUCH_EVENT
- type UserEvent C.ALLEGRO_USER_EVENT
- // Converts wrapper EventUnion pointer to C Allegro event pointer
- func (self *EventUnion) toC() *C.ALLEGRO_EVENT {
- return (*C.ALLEGRO_EVENT)(self)
- }
- // Returns an unsafe pointer to the event
- func (self *EventUnion) toPointer() unsafe.Pointer {
- return unsafe.Pointer(self.toC())
- }
- // Converts wrapper EventUnion pointer to an EventUnion interface struct
- func (evun *EventUnion) Event() Event {
- ae := (*C.ALLEGRO_ANY_EVENT)(evun.toPointer())
- switch (C.int(ae._type)) {
- case EVENT_JOYSTICK_AXIS : fallthrough
- case EVENT_JOYSTICK_BUTTON_DOWN : fallthrough
- case EVENT_JOYSTICK_BUTTON_UP : fallthrough
- case EVENT_JOYSTICK_CONFIGURATION :
- return (*JoystickEvent)(evun.toPointer())
- case EVENT_KEY_CHAR : fallthrough
- case EVENT_KEY_DOWN : fallthrough
- case EVENT_KEY_UP :
- return (*KeyboardEvent)(evun.toPointer())
- case EVENT_MOUSE_AXES : fallthrough
- case EVENT_MOUSE_BUTTON_DOWN : fallthrough
- case EVENT_MOUSE_BUTTON_UP : fallthrough
- case EVENT_MOUSE_ENTER_DISPLAY : fallthrough
- case EVENT_MOUSE_LEAVE_DISPLAY : fallthrough
- case EVENT_MOUSE_WARPED :
- return (*MouseEvent)(evun.toPointer())
-
- case EVENT_TIMER :
- return (*TimerEvent)(evun.toPointer())
-
- case EVENT_DISPLAY_EXPOSE : fallthrough
- case EVENT_DISPLAY_RESIZE : fallthrough
- case EVENT_DISPLAY_CLOSE : fallthrough
- case EVENT_DISPLAY_LOST : fallthrough
- case EVENT_DISPLAY_FOUND : fallthrough
- case EVENT_DISPLAY_SWITCH_IN : fallthrough
- case EVENT_DISPLAY_SWITCH_OUT : fallthrough
- case EVENT_DISPLAY_ORIENTATION :
- return (*DisplayEvent)(evun.toPointer())
- default: break
- }
-
- if EVENT_TYPE_IS_USER(int(ae._type)) {
- return (*UserEvent)(evun.toPointer())
- }
-
- return (*AnyEvent)(evun.toPointer())
- }
- /* These wrappers implement the interface Event for all event types */
- func (ev AnyEvent ) Type() int { return int(ev._type); }
- func (ev DisplayEvent ) Type() int { return int(ev._type); }
- func (ev JoystickEvent) Type() int { return int(ev._type); }
- func (ev KeyboardEvent) Type() int { return int(ev._type); }
- func (ev MouseEvent ) Type() int { return int(ev._type); }
- func (ev TimerEvent ) Type() int { return int(ev._type); }
- func (ev TouchEvent ) Type() int { return int(ev._type); }
- func (ev UserEvent ) Type() int { return int(ev._type); }
- func (ev AnyEvent ) Source() EventSourcer { return wrapEventSourceRaw (ev.source); }
- func (ev DisplayEvent ) Source() EventSourcer { return wrapDisplayRaw (ev.source); }
- func (ev JoystickEvent) Source() EventSourcer { return wrapJoystickRaw (ev.source); }
- func (ev KeyboardEvent) Source() EventSourcer { return wrapKeyboardRaw (ev.source); }
- func (ev MouseEvent ) Source() EventSourcer { return wrapMouseRaw (ev.source); }
- func (ev TimerEvent ) Source() EventSourcer { return wrapTimerRaw (ev.source); }
- func (ev TouchEvent ) Source() EventSourcer { return wrapTouchInputRaw (ev.source); }
- func (ev UserEvent ) Source() EventSourcer { return wrapEventSourceRaw (ev.source); }
- func (ev AnyEvent ) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev DisplayEvent ) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev JoystickEvent) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev KeyboardEvent) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev MouseEvent ) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev TimerEvent ) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev TouchEvent ) Timestamp() float64 { return float64(ev.timestamp); }
- func (ev UserEvent ) Timestamp() float64 { return float64(ev.timestamp); }
- func (eu * EventUnion) AnyEvent () *AnyEvent { return (*AnyEvent )(eu.toPointer()); }
- func (eu * EventUnion) DisplayEvent () *DisplayEvent { if !eu.IsDisplayEvent () { return nil; } else { return (*DisplayEvent )(eu.toPointer());}; }
- func (eu * EventUnion) JoystickEvent() *JoystickEvent { if !eu.IsJoystickEvent() { return nil; } else { return (*JoystickEvent)(eu.toPointer());}; }
- func (eu * EventUnion) KeyboardEvent() *KeyboardEvent { if !eu.IsKeyboardEvent() { return nil; } else { return (*KeyboardEvent)(eu.toPointer());}; }
- func (eu * EventUnion) MouseEvent () *MouseEvent { if !eu.IsMouseEvent () { return nil; } else { return (*MouseEvent )(eu.toPointer());}; }
- func (eu * EventUnion) TimerEvent () *TimerEvent { if !eu.IsTimerEvent () { return nil; } else { return (*TimerEvent )(eu.toPointer());}; }
- func (eu * EventUnion) TouchEvent () *TouchEvent { if !eu.IsTouchEvent () { return nil; } else { return (*TouchEvent )(eu.toPointer());}; }
- func (eu * EventUnion) UserEvent () *UserEvent { if !eu.IsUserEvent () { return nil; } else { return (*UserEvent )(eu.toPointer());}; }
- // Returns the type of the event.
- func (self *EventUnion) Type() int {
- return self.AnyEvent().Type()
- }
- // Returns the timestamp of the event.
- func (self *EventUnion) Timestamp() float64 {
- return self.AnyEvent().Timestamp()
- }
- // Returns the event source of the event
- func (self *EventUnion) Source() EventSourcer {
- return self.AnyEvent().Source()
- }
- // Returns true if this is a dispay event, false if not.
- func (self *EventUnion) IsDisplayEvent() bool {
- t := self.Type()
- return ((t >= EVENT_DISPLAY_EXPOSE) && (t <= EVENT_DISPLAY_ORIENTATION) || ((t>= EVENT_DISPLAY_CONNECTED) && (t<= EVENT_DISPLAY_DISCONNECTED) ))
- }
- // Returns true if this is a mouse event, false if not.
- func (self *EventUnion) IsMouseEvent() bool {
- t := self.Type()
- return (t >= EVENT_MOUSE_AXES) && (t <= EVENT_MOUSE_WARPED)
- }
- // Returns true if this is a Joystick event, false if not.
- func (self *EventUnion) IsJoystickEvent() bool {
- t := self.Type()
- return (t >= EVENT_JOYSTICK_AXIS) && (t <= EVENT_JOYSTICK_CONFIGURATION)
- }
- // Returns true if this is a keyboard event, false if not.
- func (self *EventUnion) IsKeyboardEvent() bool {
- t := self.Type()
- return (t >= EVENT_KEY_DOWN) && (t <= EVENT_KEY_UP)
- }
- // Returns true if this is a keyboard event, false if not.
- func (self *EventUnion) IsTouchEvent() bool {
- t := self.Type()
- return (t >= EVENT_TOUCH_BEGIN) && (t <= EVENT_TOUCH_CANCEL)
- }
- // Returns true if this is a timer event, false if not.
- func (self *EventUnion) IsTimerEvent() bool {
- t := self.Type()
- return (t == EVENT_TIMER)
- }
- // Returns true if this is a user event, false if not.
- func (self *EventUnion) IsUserEvent() bool {
- t := self.Type()
- return EVENT_TYPE_IS_USER(t)
- }
- // Returns the X position of the display event.
- func (de DisplayEvent) X() int {
- return int(de.x)
- }
- // Returns the Y position of the display event.
- func (de DisplayEvent) Y() int {
- return int(de.y)
- }
- // Returns the width of the display event.
- func (de DisplayEvent) Width() int {
- return int(de.width)
- }
- // Returns the height of the display event.
- func (de DisplayEvent) Height() int {
- return int(de.height)
- }
- // Returns the orientation of the display event.
- func (de DisplayEvent) Orientation() int {
- return int(de.orientation)
- }
- // Returns the stick number of the joystick event.
- func (je JoystickEvent) Stick() int {
- return int(je.stick)
- }
- // Returns the axis number of the joystick event.
- func (je JoystickEvent) Axis() int {
- return int(je.axis)
- }
- // Returns the button number of the joystick event.
- func (je JoystickEvent) Button() int {
- return int(je.button)
- }
- // Returns the position of the joystick event.
- func (je JoystickEvent) Pos() int {
- return int(je.pos)
- }
- // Returns the display that has emitted the keyboard event.
- func (ke KeyboardEvent) Display() *Display {
- return wrapDisplayRaw(ke.display)
- }
- // Returns the key code of the keyboard event.
- func (ke KeyboardEvent) Keycode() int {
- return int(ke.keycode)
- }
- // Returns the unicode character of the keyboard event.
- func (ke KeyboardEvent) Unichar() rune {
- return rune(ke.unichar)
- }
- // Returns the modifiers of the keyboard event.
- func (ke KeyboardEvent) Modifiers() int {
- return int(ke.modifiers)
- }
- // Returns is the keyboard event was automatically repeated or not.
- func (ke KeyboardEvent) Repeat() bool {
- return bool(ke.repeat)
- }
- // Returns the X position of the mouse event.
- func (me MouseEvent) X() int {
- return int(me.x)
- }
- // Returns the Y position of the mouse event.
- func (me MouseEvent) Y() int {
- return int(me.y)
- }
- // Returns the Z position of the mouse event.
- func (me MouseEvent) Z() int {
- return int(me.z)
- }
- // Returns the W position of the mouse event.
- func (me MouseEvent) W() int {
- return int(me.w)
- }
- // Returns the delta of the X position of the mouse event.
- func (me MouseEvent) DX() int {
- return int(me.dx)
- }
- // Returns the delta of the Y position of the mouse event.
- func (me MouseEvent) DY() int {
- return int(me.dy)
- }
- // Returns the delta of the Z position of the mouse event.
- func (me MouseEvent) DZ() int {
- return int(me.dz)
- }
- // Returns the delta of the W position of the mouse event.
- func (me MouseEvent) DW() int {
- return int(me.dw)
- }
- // Returns the button of the mouse event.
- func (me MouseEvent) Button() int {
- return int(me.button)
- }
- // Returns the pressure of the mouse event.
- func (me MouseEvent) Pressure() float32 {
- return float32(me.pressure)
- }
- // Returns the display that has emitted the mouse event.
- func (me MouseEvent) Display() *Display {
- return wrapDisplayRaw(me.display)
- }
- // Returns the error of the timer event.
- func (te TimerEvent) Error() float64 {
- return float64(te.error)
- }
- // Returns the ticks of the timer event.
- func (te TimerEvent) Count() int64 {
- return int64(te.count)
- }
- // Returns the X position of the touch input event.
- func (te TouchEvent) X() int {
- return int(te.x)
- }
- // Returns the Y position of the touch input event.
- func (te TouchEvent) Y() int {
- return int(te.y)
- }
- // Returns the ID of the touch input event.
- func (te TouchEvent) ID() int {
- return int(te.id)
- }
- // Returns whether the touch input event is primary or not.
- func (te TouchEvent) Primary() bool {
- return bool(te.primary)
- }
- // Returns the delta of the X position of the touch input event.
- func (te TouchEvent) DX() int {
- return int(te.dx)
- }
- // Returns the delta of the Y position of the touch input event.
- func (te TouchEvent) DY() int {
- return int(te.dy)
- }
- /* The safest way to use user events from GO is to use integer handles
- * as offsets into a GO-allocated map. */
- func (ue UserEvent) Data1Pointer() unsafe.Pointer { return unsafe.Pointer(uintptr(ue.data1));}
- func (ue UserEvent) Data1Integer() int64 { return int64(ue.data1); }
- func (ue UserEvent) Data2Pointer() unsafe.Pointer { return unsafe.Pointer(uintptr(ue.data2));}
- func (ue UserEvent) Data2Integer() int64 { return int64(ue.data2); }
- func (ue UserEvent) Data3Pointer() unsafe.Pointer { return unsafe.Pointer(uintptr(ue.data3));}
- func (ue UserEvent) Data3Integer() int64 { return int64(ue.data3); }
- func (ue UserEvent) Data4Pointer() unsafe.Pointer { return unsafe.Pointer(uintptr(ue.data4));}
- func (ue UserEvent) Data4Integer() int64 { return int64(ue.data4); }
- func (ue UserEvent) SetData1Integer(v int64) { ue.data1 = C.intptr_t(v); }
- func (ue UserEvent) SetData2Integer(v int64) { ue.data2 = C.intptr_t(v); }
- func (ue UserEvent) SetData3Integer(v int64) { ue.data3 = C.intptr_t(v); }
- func (ue UserEvent) SetData4Integer(v int64) { ue.data4 = C.intptr_t(v); }
- /*
- The compiler accept this, but it's unlikely to work correctly.
- func (ue UserEvent) Data1() interface{} { return (interface{})(ue.Data1Pointer());}
- func (ue UserEvent) Data2() interface{} { return (interface{})(ue.Data2Pointer());}
- func (ue UserEvent) Data3() interface{} { return (interface{})(ue.Data3Pointer());}
- func (ue UserEvent) Data4() interface{} { return (interface{})(ue.Data4Pointer());}
- */
- // Event queues.
- type EventQueue struct {
- handle *C.ALLEGRO_EVENT_QUEUE
- }
- // Destroys the event queue.
- func (self *EventQueue) Destroy() {
- if self.handle != nil {
- C.al_destroy_event_queue(self.handle)
- }
- self.handle = nil
- }
- // Wraps an event queue, but does not set a finalizer.
- func wrapEventQueueRaw(handle *C.ALLEGRO_EVENT_QUEUE) *EventQueue {
- if handle == nil {
- return nil
- }
- return &EventQueue{handle}
- }
- func (eq * EventQueue) toC() (handle *C.ALLEGRO_EVENT_QUEUE) {
- return eq.handle
- }
- // Wraps an event queue and sets a finalizer that calls Destroy
- func wrapEventQueue(handle *C.ALLEGRO_EVENT_QUEUE) *EventQueue {
- result := wrapEventQueueRaw(handle)
- if result != nil {
- runtime.SetFinalizer(result, func(me *EventQueue) { me.Destroy() })
- }
- return result
- }
- // Create an event queue.
- func CreateEventQueue() *EventQueue {
- return wrapEventQueue(C.al_create_event_queue())
- }
- // Register an event source with self.
- func (self *EventQueue) RegisterEventSource(src *EventSource) {
- C.al_register_event_source(self.handle, src.toC())
- }
- // Unregister an event source with self.
- func (self *EventQueue) UnregisterEventSource(src *EventSource) {
- C.al_unregister_event_source(self.handle, src.toC())
- }
- // Returns true if the event queue self is empty, false if not.
- func (self *EventQueue) IsEmpty() bool {
- return bool(C.al_is_event_queue_empty(self.handle))
- }
- // Returns the next event from the event queue as well as a bool
- // to signify if an event was fetched sucessfully or not.
- func (self *EventQueue) GetNextEvent() (event *EventUnion, ok bool) {
- event = &EventUnion{}
- ok = bool(C.al_get_next_event(self.handle, event.toC()))
- return event, ok
- }
- // Peeks at the next event in the event queue and returns it as well as a bool
- // to signify if an event was fetched sucessfully or not.
- func (self *EventQueue) PeekNextEvent() (event *EventUnion, ok bool) {
- event = &EventUnion{}
- ok = bool(C.al_peek_next_event(self.handle, event.toC()))
- return event, ok
- }
- // Drops the next event from the event queue
- func (self *EventQueue) DropNextEvent() bool {
- return bool(C.al_drop_next_event(self.handle))
- }
- // Flushes the event queue
- func (self *EventQueue) Flush() {
- C.al_flush_event_queue(self.handle)
- }
- // Waits for the next event from the event queue
- func (self *EventQueue) WaitForEvent() (event *EventUnion) {
- event = &EventUnion{}
- C.al_wait_for_event(self.handle, event.toC())
- return event
- }
- // Waits for secs seconds the next event from the event queue
- func (self *EventQueue) WaitForEventTimed(secs float32) (event *EventUnion, ok bool) {
- event = &EventUnion{}
- ok = bool(C.al_wait_for_event_timed(self.handle, event.toC(), C.float(secs)))
- return event, ok
- }
- func (queue *EventQueue) WaitForEventUntil(timeout * Timeout) (event *EventUnion, ok bool) {
- event = &EventUnion{}
- ok = bool(C.al_wait_for_event_until(queue.toC(), event.toC(), timeout.toC()))
- return event, ok
- }
|