diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index e76c76e..ddfd9a9 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -588,3 +588,141 @@ extend Apex ^Association new key: self value: object } } + +## ------------------------------------------------------------------------------- + +class Link(Object) +{ + dcl prev next value. + + method(#class) new: value + { + | x | + x := self new. + x value: value. + ^x + } + + method prev { ^self.prev } + method next { ^self.next } + method value { ^self.value } + method prev: link { self.prev := link } + method next: link { self.next := link } + method value: value { self.value := value } +} + +class LinkedList(Collection) +{ + dcl first last tally. + + method initialize + { + self.tally := 0. + } + + method size + { + ^self.tally + } + + method first + { + ^self.first + } + + method last + { + ^self.last + } + + method insertLink: link at: pos + { + if (pos isNil) + { + (* add link at the back *) + if (self.tally == 0) + { + self.first := link. + self.last := link. + link prev: nil. + } + else + { + link prev: self.last. + self.last next: link. + self.last := link. + }. + link next: nil. + } + else + { + (* insert the link before pos *) + link next: pos. + link prev: pos prev. + if (pos prev notNil) { pos prev next: link } + else { self.first := link }. + pos prev: link + }. + + self.tally := self.tally + 1. + ^link + } + + method insert: value at: pos + { + ^self insertLink: (Link new: value) at: pos + } + + method addFirst: value + { + ^self insert: value at: self.first + } + + method addLast: value + { + ^self insert: value at: nil + } + + method addFirstLink: link + { + ^self insertLink: link at: self.first + } + + method addLastLink: link + { + ^self insertLink: link at: nil + } + + method removeLink: link + { + if (link next notNil) { link next prev: link prev } + else { self.last := link prev }. + + if (link prev notNil) { link prev next: link next } + else { self.first := link next }. + + self.tally := self.tally - 1. + } + + method removeFirst + { + ^self removeLink: self.first + } + + method removeLast + { + ^self removeLink: self.last + } + + method do: block + { + | link next | + link := self.first. + while (link notNil) + { + next := link next. + block value: link value. + link := next. + } + } +} diff --git a/moo/kernel/Magnitu.moo b/moo/kernel/Magnitu.moo index 76ebe4e..880e233 100644 --- a/moo/kernel/Magnitu.moo +++ b/moo/kernel/Magnitu.moo @@ -187,65 +187,105 @@ class Number(Magnitude) self primitiveFailed. } - method to: end by: step do: aBlock + method to: end by: step do: block { | i | i := self. + (* (step > 0) ifTrue: [ [ i <= end ] whileTrue: [ - aBlock value: i. + block value: i. i := i + step. ]. ] ifFalse: [ [ i >= end ] whileTrue: [ - aBlock value: i. + block value: i. i := i - step. ]. ]. + *) + if (step > 0) + { + while (i <= end) + { + block value: i. + i := i + step. + } + } + else + { + while ( i => end) + { + block value: i. + i := i - step. + } + } } - method to: end do: aBlock + method to: end do: block { - ^self to: end by: 1 do: aBlock. + ^self to: end by: 1 do: block. } - method priorTo: end by: step do: aBlock + method priorTo: end by: step do: block { | i | i := self. + (* (step > 0) ifTrue: [ [ i < end ] whileTrue: [ - aBlock value: i. + block value: i. i := i + step. ]. ] ifFalse: [ [ i > end ] whileTrue: [ - aBlock value: i. + block value: i. i := i - step. ]. ]. + *) + if (step > 0) + { + while (i < end) + { + block value: i. + i := i + step. + } + } + else + { + while ( i > end) + { + block value: i. + i := i - step. + } + } } - method priorTo: end do: aBlock + method priorTo: end do: block { - ^self priorTo: end by: 1 do: aBlock. + ^self priorTo: end by: 1 do: block. } method abs { - self < 0 ifTrue: [^self negated]. - ^self. + (*self < 0 ifTrue: [^self negated]. + ^self.*) + ^if (self < 0) { self negated } else { self } } method sign { - self < 0 ifTrue: [^-1]. + (* self < 0 ifTrue: [^-1]. self > 0 ifTrue: [^1]. - ^0. + ^0.*) + ^if (self < 0) { -1 } + elsif (self > 0) { 1 } + else { 0 } } } @@ -281,26 +321,12 @@ class(#liword) LargeInteger(Integer) class(#liword) LargePositiveInteger(LargeInteger) { - method abs - { - ^self. - } - - method sign - { - ^1. - } + method abs { ^self } + method sign { ^1 } } class(#liword) LargeNegativeInteger(LargeInteger) { - method abs - { - ^self negated. - } - - method sign - { - ^-1. - } + method abs { ^self negated } + method sign { ^-1 } } diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 47cadd0..4c87a33 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -3162,12 +3162,10 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) if (moo->sem_io_wait_count > 0) { -MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT()\n"); vm_vm_muxwait (moo, &ft); } else { -MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_SLEEP()\n"); vm_sleep (moo, &ft); } vm_gettime (moo, &now); @@ -3183,7 +3181,6 @@ MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_SLEEP()\n"); if (moo->sem_io_wait_count > 0) { -MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT 222()\n"); vm_vm_muxwait (moo, MOO_NULL); } diff --git a/moo/lib/main.c b/moo/lib/main.c index 4aeb96a..c42a436 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -134,6 +134,7 @@ struct xtn_t #if defined(USE_THREAD) int p[2]; /* pipe for signaling */ pthread_t iothr; + int iothr_up; int iothr_abort; struct { @@ -800,7 +801,8 @@ static int vm_startup (moo_t* moo) pthread_cond_init (&xtn->ev.cnd2, MOO_NULL); xtn->iothr_abort = 0; - pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo); + xtn->iothr_up = 0; + /*pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo);*/ #endif return 0; @@ -837,9 +839,13 @@ static void vm_cleanup (moo_t* moo) xtn_t* xtn = (xtn_t*)moo_getxtn(moo); #if defined(USE_THREAD) - write (xtn->p[1], "Q", 1); - pthread_cond_signal (&xtn->ev.cnd); - pthread_join (xtn->iothr, MOO_NULL); + if (xtn->iothr_up) + { + write (xtn->p[1], "Q", 1); + pthread_cond_signal (&xtn->ev.cnd); + pthread_join (xtn->iothr, MOO_NULL); + xtn->iothr_up = 0; + } pthread_cond_destroy (&xtn->ev.cnd); pthread_cond_destroy (&xtn->ev.cnd2); pthread_mutex_destroy (&xtn->ev.mtx); @@ -973,6 +979,18 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c #if defined(USE_THREAD) int n; + /* create a thread if mux wait is started at least once. */ + if (!xtn->iothr_up) + { + xtn->iothr_up = 1; + if (pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo) != 0) + { + MOO_LOG2 (moo, MOO_LOG_WARN, "Warning: pthread_create failure - %d, %hs\n", errno, strerror(errno)); + xtn->iothr_up = 0; +/* TODO: switch to the non-threaded mode? */ + } + } + if (xtn->ev.len <= 0) { struct timespec ts; @@ -1016,6 +1034,7 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c else if (muxwcb) { int mask = 0; + if (xtn->ev.buf[n].events & EPOLLIN) mask |= MOO_SEMAPHORE_IO_MASK_INPUT; if (xtn->ev.buf[n].events & EPOLLOUT) mask |= MOO_SEMAPHORE_IO_MASK_OUTPUT; if (xtn->ev.buf[n].events & EPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR; @@ -1049,6 +1068,9 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c xtn->ev.len = n; } + /* the muxwcb must be valid all the time in a non-threaded mode */ + MOO_ASSERT (moo, muxwcb != MOO_NULL); + while (n > 0) { int mask; @@ -1124,7 +1146,8 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur) #if defined(USE_THREAD) /* the sleep callback is called only if there is no IO semaphore - * waiting. so i can safely use vm_muxwait when USE_THREAD is true */ + * waiting. so i can safely call vm_muxwait() wihtout a muxwait callback + * when USE_THREAD is true */ vm_muxwait (moo, dur, MOO_NULL); #else struct timespec ts; diff --git a/moo/lib/obj.c b/moo/lib/obj.c index cabad2c..70755b7 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -225,7 +225,7 @@ static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_class_t _class, moo_oow_t if (vlen > 0) { - MOO_DEBUG2 (moo, "Unamed instance variables for a fixed class %O - %zu\n", _class, vlen); + MOO_DEBUG2 (moo, "Unnamed instance variables for a fixed class %O - %zu\n", _class, vlen); return -1; } /*vlen = 0;*/ /* vlen is not used */ diff --git a/moo/mod/x11.c b/moo/mod/x11.c index 7bd73bf..6971aea 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -39,14 +39,14 @@ typedef struct x11_t x11_t; struct x11_t { xcb_connection_t* c; - xcb_window_t w; - xcb_intern_atom_reply_t* dwcr; /* TODO: move this to each window */ + xcb_screen_t* screen; }; typedef struct x11_win_t x11_win_t; struct x11_win_t { - xcb_window_t w; + xcb_window_t id; + xcb_intern_atom_reply_t* dwcr; }; /* ------------------------------------------------------------------------ */ @@ -89,7 +89,9 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) goto softfail; } + x11->screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data; x11->c = c; + MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -158,12 +160,17 @@ static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) { uint8_t evttype = evt->response_type & ~0x80; - if (evttype == XCB_CLIENT_MESSAGE && + if (evttype == XCB_CLIENT_MESSAGE) +#if 0 +&& ((xcb_client_message_event_t*)evt)->data.data32[0] == x11->dwcr->atom) +#endif { +#if 0 xcb_unmap_window (x11->c, x11->w); xcb_destroy_window (x11->c, x11->w); xcb_flush (x11->c); +#endif MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(9999)); /* TODO: translate evt to the event object */ } else @@ -174,30 +181,33 @@ static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) } else { -MOO_DEBUG0(moo, "BBBBBBBBBBBBbb GOT NO EVENT...\n"); MOO_STACK_SETRET (moo, nargs, moo->_nil); } return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_makewin (moo_t* moo, moo_ooi_t nargs) +/* ------------------------------------------------------------------------ */ + +static moo_pfrc_t pf_win_make_on (moo_t* moo, moo_ooi_t nargs) { x11_t* x11; - xcb_screen_t* screen; + x11_win_t* win; + uint32_t mask; uint32_t values[2]; xcb_intern_atom_cookie_t cookie; xcb_intern_atom_reply_t* reply; - x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); - MOO_DEBUG1 (moo, " %p\n", x11->c); +MOO_DEBUG0 (moo, " %p\n"); - screen = xcb_setup_roots_iterator(xcb_get_setup(x11->c)).data; - x11->w = xcb_generate_id (x11->c); + x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL); + win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + + win->id = xcb_generate_id (x11->c); mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - values[0] = screen->white_pixel; + values[0] = x11->screen->white_pixel; values[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | @@ -208,43 +218,50 @@ static moo_pfrc_t pf_makewin (moo_t* moo, moo_ooi_t nargs) xcb_create_window ( x11->c, XCB_COPY_FROM_PARENT, - x11->w, - screen->root, + win->id, + x11->screen->root, 0, 0, 300, 300, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, - screen->root_visual, + x11->screen->root_visual, mask, values); cookie = xcb_intern_atom(x11->c, 1, 12, "WM_PROTOCOLS"); reply = xcb_intern_atom_reply(x11->c, cookie, 0); cookie = xcb_intern_atom(x11->c, 0, 16, "WM_DELETE_WINDOW"); - x11->dwcr = xcb_intern_atom_reply(x11->c, cookie, 0); + win->dwcr = xcb_intern_atom_reply(x11->c, cookie, 0); - xcb_change_property(x11->c, XCB_PROP_MODE_REPLACE, x11->w, reply->atom, 4, 32, 1, &x11->dwcr->atom); + xcb_change_property(x11->c, XCB_PROP_MODE_REPLACE, win->id, reply->atom, 4, 32, 1, &win->dwcr->atom); /*TODO: use xcb_request_check() for error handling. you need to call create_x11->wdwo_checked(). xxx_checked()... */ - xcb_map_window (x11->c, x11->w); + xcb_map_window (x11->c, win->id); xcb_flush (x11->c); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(x11->w)); /* TODO: write this function to return a window handle... */ + MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; } - -/* ------------------------------------------------------------------------ */ - -static moo_pfrc_t pf_win_create (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_win_kill_on (moo_t* moo, moo_ooi_t nargs) { - MOO_STACK_SETRET (moo, nargs, moo->_nil); -MOO_DEBUG0 (moo, "x11.window.create....\n"); - return MOO_PF_SUCCESS; -} + x11_t* x11; + x11_win_t* win; -static moo_pfrc_t pf_win_destroy (moo_t* moo, moo_ooi_t nargs) -{ - MOO_STACK_SETRET (moo, nargs, moo->_nil); -MOO_DEBUG0 (moo, "x11.window.destroy....\n"); + x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL); + win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + + if (!x11->c) + { + MOO_STACK_SETRETTOERROR (moo, nargs); /* More specific error code*/ + return MOO_PF_SUCCESS; + } + +/* TODO: check on windows id */ + + xcb_unmap_window (x11->c, win->id); /* TODO: check error code */ + xcb_destroy_window (x11->c, win->id); + xcb_flush (x11->c); + + MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; } @@ -253,11 +270,10 @@ MOO_DEBUG0 (moo, "x11.window.destroy....\n"); static moo_pfinfo_t x11_pfinfo[] = { - { I, { '_','_','g','e','t','e','v','e','n','t','\0'}, 0, pf_getevent }, - { I, { '_','_','m','a','k','e','w','i','n','\0'}, 0, pf_makewin }, - { I, { 'c','o','n','n','e','c','t','\0' }, 0, pf_connect }, - { I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect }, - { I, { 'g','e','t','f','d','\0' }, 0, pf_getfd } + { I, { '_','g','e','t','e','v','e','n','t','\0'}, 0, pf_getevent }, + { I, { 'c','o','n','n','e','c','t','\0' }, 0, pf_connect }, + { I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect }, + { I, { 'g','e','t','f','d','\0' }, 0, pf_getfd } }; @@ -291,14 +307,15 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) static moo_pfinfo_t x11_win_pfinfo[] = { - { I, { 'c','r','e','a','t','e','\0' }, 0, pf_win_create }, - { I, { 'd','i','s','t','r','o','y','\0' }, 0, pf_win_destroy } + { I, { '_','m','a','k','e','_','o','n',':','\0' }, 0, pf_win_make_on }, + { I, { '_','k','i','l','l','_','o','n',':','\0' }, 0, pf_win_kill_on } }; static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1; - return moo_genpfmethods(moo, mod, _class, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo)); + /*return moo_genpfmethods(moo, mod, _class, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo));*/ + return 0; } static moo_pfimpl_t x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name)