From 3b799c198219444a853f986640e2eeaed20b4ad2 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Thu, 26 Mar 2009 03:01:26 +0100 Subject: [PATCH] library: move example code into library and strip example --- configure.ac | 8 +- eflvala/Makefile.am | 2 + eflvala/application.vala | 58 +++++- eflvala/notificationqueue.vala | 4 +- eflvala/objects.vala | 23 ++- eflvala/thread.vala | 154 +++++++++++++- examples/library/mainloops.vala | 261 ++++++------------------ examples/vapi/main.vala | 27 ++- tests/.gitignore | 2 +- tests/Makefile.am | 13 ++ tests/testelementary.vala | 24 ++- eflvala/application.vala => tests/testevas.vala | 25 ++- 12 files changed, 353 insertions(+), 248 deletions(-) rewrite examples/library/mainloops.vala (76%) copy eflvala/application.vala => tests/testevas.vala (75%) diff --git a/configure.ac b/configure.ac index 21e979d..4f2600a 100644 --- a/configure.ac +++ b/configure.ac @@ -15,12 +15,18 @@ AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) +EINA_REQUIRED=0.0.0 EVAS_REQUIRED=0.0.0 ECORE_REQUIRED=0.0.0 ELM_REQUIRED=0.0.0 GLIB_REQUIRED=2.18.0 +DBUS_REQUIRED=1.1.1 +DBUS_GLIB_REQUIRED=0.74 PKG_CHECK_MODULES(DEPS, + dbus-1 >= $DBUS_REQUIRED + dbus-glib-1 >= $DBUS_GLIB_REQUIRED + eina-0 >= $EINA_REQUIRED evas >= $EVAS_REQUIRED ecore >= $ECORE_REQUIRED elementary >= $ELM_REQUIRED @@ -55,7 +61,7 @@ if test "$enable_library" != no; then else AC_MSG_RESULT(no) fi - + # shall we compile the examples? [default=yes] AC_ARG_ENABLE(examples, [ --disable-examples skip building the examples [[default=no]]]) AM_CONDITIONAL(MAKE_EXAMPLES, test x$enable_examples != xno) diff --git a/eflvala/Makefile.am b/eflvala/Makefile.am index a2c1517..2529133 100644 --- a/eflvala/Makefile.am +++ b/eflvala/Makefile.am @@ -44,6 +44,7 @@ libeflvala_la_SOURCES = \ .vala.stamp: $(libeflvala_la_VALASOURCES) $(VALAC) -c --vapidir $(top_srcdir)/vapi \ + --pkg dbus-glib-1 \ --pkg eina \ --pkg evas \ --pkg ecore \ @@ -51,6 +52,7 @@ libeflvala_la_SOURCES = \ --pkg posix \ --library=eflvala-1.0 \ --save-temps \ + --thread \ --basedir $(top_srcdir) $^ touch $@ diff --git a/eflvala/application.vala b/eflvala/application.vala index d7b47f6..e851486 100644 --- a/eflvala/application.vala +++ b/eflvala/application.vala @@ -17,11 +17,63 @@ * **/ +static EflVala.Application theApp; + //======================================================================= public class EflVala.Application : GLib.Object //======================================================================= { - // owns and creates the two threads - // sets up the communication infrastructure - // contains methods to register for communication events + private EflVala.EThread _ethread; + private EflVala.GThread _gthread; + + // + // public + // + + public Application( string[] args ) + { + debug( "Application()" ); + Elm.init( args ); //FIXME: might be better done elsewhere (i.e. from within the E thread?) + assert ( theApp == null ); + theApp = this; + _createThreads(); + } + + public int run() + { + _ethread.run(); + _gthread.run(); + _ethread.join(); + _gthread.join(); + return 0; + } + + public void quit() + { + _ethread.quit(); + _gthread.quit(); + } + + public virtual void setupFrontend() + { + } + + public virtual void setupBackend() + { + } + + // + // private + // + + private void _createThreads() + { + if ( !GLib.Thread.supported() ) + { + error( "Cannot run without threads!" ); + } + + _ethread = new EflVala.EThread(); + _gthread = new EflVala.GThread(); + } } diff --git a/eflvala/notificationqueue.vala b/eflvala/notificationqueue.vala index 1955129..da3c8af 100644 --- a/eflvala/notificationqueue.vala +++ b/eflvala/notificationqueue.vala @@ -21,14 +21,14 @@ public class EflVala.QueueWithNotifier : GLib.Object //======================================================================= { - private Queue q; + private GLib.Queue q; private static int counter = 0; private int readfd = -1; private int writefd = -1; public QueueWithNotifier() { - q = new Queue(); + q = new GLib.Queue(); int[] fds = { 0, 0 }; var ok = Posix.pipe( fds ); if ( ok == -1 ) diff --git a/eflvala/objects.vala b/eflvala/objects.vala index 87f3b5b..eb62ced 100644 --- a/eflvala/objects.vala +++ b/eflvala/objects.vala @@ -46,8 +46,8 @@ public class EflVala.BidirectionalThreadQueue : GLib.Object COMMUNICATION_THREAD, GUI_THREAD; } - private static QueueWithNotifier toGuiQ; - private static QueueWithNotifier toCommQ; + private static EflVala.QueueWithNotifier toGuiQ; + private static EflVala.QueueWithNotifier toCommQ; private Identifier owner; @@ -58,11 +58,11 @@ public class EflVala.BidirectionalThreadQueue : GLib.Object { case Identifier.COMMUNICATION_THREAD: assert ( toGuiQ == null ); - toGuiQ = new QueueWithNotifier(); + toGuiQ = new EflVala.QueueWithNotifier(); break; case Identifier.GUI_THREAD: assert ( toCommQ == null ); - toCommQ = new QueueWithNotifier(); + toCommQ = new EflVala.QueueWithNotifier(); break; default: assert_not_reached(); @@ -86,6 +86,21 @@ public class EflVala.BidirectionalThreadQueue : GLib.Object } } + public int getReadFd() + { + switch ( owner ) + { + case Identifier.COMMUNICATION_THREAD: + return toCommQ.getReadFd(); + break; + case Identifier.GUI_THREAD: + return toGuiQ.getReadFd(); + break; + default: + assert_not_reached(); + } + } + public Command? read() { switch ( owner ) diff --git a/eflvala/thread.vala b/eflvala/thread.vala index 99116ca..300da75 100644 --- a/eflvala/thread.vala +++ b/eflvala/thread.vala @@ -17,7 +17,11 @@ * **/ +public delegate bool EflVala.FdCallback( int fd ); + +//======================================================================= public class EflVala.Thread : GLib.Object +//======================================================================= { private unowned GLib.Thread _thread; @@ -37,13 +41,151 @@ public class EflVala.Thread : GLib.Object _thread = GLib.Thread.create( _run, true ); } + public void join() + { + assert ( _thread != null ); + _thread.join(); + } + + public virtual void mainfunc() + { + } + + public virtual void quit() + { + } + + public virtual bool command( EflVala.Command cmd ) + { + return false; + } + + // + // internal + // + private void* _run() { - debug( "_run..." ); - while ( true ) - { - debug( "still running..." ); - _thread.usleep( 1000 * 300 ); - } + mainfunc(); + return null; + } +} + +//======================================================================= +public class EflVala.GThread : EflVala.Thread +//======================================================================= +{ + private GLib.MainLoop mainloop; + private GLib.IOChannel iochannel; + private EflVala.BidirectionalThreadQueue q; + + public GThread() + { + debug( "constructing G thread" ); + // create mainloop + mainloop = new GLib.MainLoop( null, false ); + // create commqueue + q = new EflVala.BidirectionalThreadQueue( EflVala.BidirectionalThreadQueue.Identifier.COMMUNICATION_THREAD ); + } + + public override void mainfunc() + { + debug( "G mainfunc" ); + // give app a chance to init its backend + theApp.setupBackend(); + // setup debug watcher + Timeout.add_seconds( 1, _secondsTimeout ); + // hook q into mainloop + iochannel = new GLib.IOChannel.unix_new( q.getReadFd() ); + iochannel.add_watch( GLib.IOCondition.IN, _canReadFromQueue ); + // and run + mainloop.run(); + } + + public override void quit() + { + mainloop.quit(); + } + + public override bool command( EflVala.Command cmd ) + { + debug( "G Thread got command: '%s'", cmd.command ); + return true; + } + + // + // internal + // + private bool _canReadFromQueue( GLib.IOChannel source, GLib.IOCondition condition ) + { + return command( q.read() ); + } + + private bool _secondsTimeout() + { + debug( "G still running" ); + return true; + } +} + +//======================================================================= +public class EflVala.EThread : EflVala.Thread +//======================================================================= +{ + private EflVala.BidirectionalThreadQueue q; + private Ecore.Timer timer; + private Ecore.FdHandler fdhandler; + + public EThread() + { + debug( "constructing E thread" ); + // create mainloop + //Elm.init( theApp.args() ); + // create commqueue + q = new EflVala.BidirectionalThreadQueue( EflVala.BidirectionalThreadQueue.Identifier.GUI_THREAD ); + } + + ~EThread() + { + Elm.shutdown(); + } + + public override void mainfunc() + { + debug( "E mainfunc" ); + // give app a chance to init its frontend + theApp.setupFrontend(); + // setup debug watcher + timer = new Ecore.Timer( 1.0, _secondsTimeout ); + // hook q into mainloop + fdhandler = new Ecore.FdHandler( q.getReadFd(), Ecore.FdHandlerFlags.READ, _canReadFromQueue, null ); + // and run + Elm.run(); + } + + public override void quit() + { + Elm.exit(); + } + + public override bool command( EflVala.Command cmd ) + { + debug( "E Thread got command: '%s'", cmd.command ); + return true; + } + + // + // internal + // + + private bool _canReadFromQueue( Ecore.FdHandler fdhandler ) + { + return command( q.read() ); + } + + private bool _secondsTimeout() + { + debug( "E still running" ); + return true; } } diff --git a/examples/library/mainloops.vala b/examples/library/mainloops.vala dissimilarity index 76% index c8cae1a..463c7d6 100644 --- a/examples/library/mainloops.vala +++ b/examples/library/mainloops.vala @@ -1,199 +1,62 @@ -/** - * Copyright (C) 2009 Michael 'Mickey' Lauer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - **/ - -// This is for testing how to best deal with the two distinct threads, -// it may evolve in a Application class in libeflvala that hides the -// nasty details of the two threads / mainloops involved. - -public class CommunicationThread : GLib.Object -{ - bool quitflag; - - public static CommunicationThread self; - public static MainLoop loop; - - public EflVala.BidirectionalThreadQueue q; - private IOChannel ioc; - - public CommunicationThread() - { - assert ( self == null ); - self = this; - q = new EflVala.BidirectionalThreadQueue( EflVala.BidirectionalThreadQueue.Identifier.COMMUNICATION_THREAD ); - } - - public bool canReadFromQ( IOChannel source, IOCondition c ) - { - debug( "G thread can read from Q" ); - var command = q.read(); - debug( "G thread got command '%s", command.command ); - q.write( new EflVala.Command( "G --> E") ); - q.write( new EflVala.Command( "G --> E") ); - return true; - } - - public bool watcher() - { - debug( "G mainloop still running" ); - if ( !quitflag ) - return true; - else - { - loop.quit(); - return false; - } - } - - public void shutdown() - { - quitflag = true; - } - - public static void* run() - { - assert ( self != null ); - loop = new MainLoop( null, false ); - Timeout.add_seconds( 1, self.watcher ); - int readfd; - int writefd; - self.q.getFds( out readfd, out writefd ); - self.ioc = new GLib.IOChannel.unix_new( readfd ); - self.ioc.add_watch( IOCondition.IN, self.canReadFromQ ); - debug( "INTO G mainloop" ); - loop.run(); - debug( "OUT OF G mainloop" ); - return null; - } -} - -public class UserInterfaceThread : GLib.Object -{ - public static UserInterfaceThread self; - public CommunicationThread commthread; - public Ecore.Timer timer; - public Elm.Win win; - - public Ecore.FdHandler fdhandler; - - public EflVala.BidirectionalThreadQueue q; - - public UserInterfaceThread( string[] args ) - { - assert ( self == null ); - self = this; - - q = new EflVala.BidirectionalThreadQueue( EflVala.BidirectionalThreadQueue.Identifier.GUI_THREAD ); - - Elm.init( args ); - - win = new Elm.Win( null, "myWindow", Elm.WinType.BASIC ); - win.title_set( "Elementary meets Vala" ); - win.autodel_set( true ); - win.resize( 320, 320 ); - win.smart_callback_add( "delete-request", Elm.exit ); - win.show(); - - var layout = new Elm.Layout( win ); - layout.file_set( "/usr/local/share/elementary/objects/test.edj", "layout" ); - layout.size_hint_weight_set( 1.0, 1.0 ); - layout.show(); - win.resize_object_add( layout ); - - } - - public void setCommThread( CommunicationThread commthread ) - { - this.commthread = commthread; - } - - ~UserInterfaceThread() - { - Elm.shutdown(); - } - - public bool watcher() - { - debug( "E mainloop still running" ); - q.write( new EflVala.Command( "E --> G" ) ); - return true; - } - - public bool canReadFromQ( Ecore.FdHandler fdhandler ) - { - debug( "E thread can read from Q" ); - var command = q.read(); - debug( "E thread got command '%s", command.command ); - return true; - } - - public static void* run() - { - self.timer = new Ecore.Timer( 1, self.watcher ); - - int writefd; - int readfd; - self.q.getFds( out readfd, out writefd ); - - self.fdhandler = new Ecore.FdHandler( readfd, Ecore.FdHandlerFlags.READ, self.canReadFromQ, null ); - - debug( "INTO E mainloop" ); - Elm.run(); - debug( "OUT OF E mainloop" ); - self.commthread.shutdown(); - return null; - } - -} - -static int main( string[] args ) -{ - if ( !Thread.supported() ) { - error( "Cannot run without threads.\n" ); - return 0; - } - - var commt = new CommunicationThread(); - var uit = new UserInterfaceThread( args ); - uit.setCommThread( commt ); - - unowned Thread t1; - unowned Thread t2; - - try - { - t1 = Thread.create( commt.run, true ); - t2 = Thread.create( uit.run, true ); - - var t3 = new EflVala.Thread(); - t3.run(); - } - catch ( ThreadError ex ) - { - error( "%s", ex.message ); - return -1; - } - - t1.join(); - t2.join(); - - debug( "all threads exited OK." ); - - return 0; -} - +/** + * Copyright (C) 2009 Michael 'Mickey' Lauer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + **/ + +//======================================================================= +class DemoApplication : EflVala.Application +//======================================================================= +{ + Elm.Win win; + Elm.Layout layout; + + public DemoApplication( string[] args ) + { + base( args ); + setup(); + } + + public void setup() + { + win = new Elm.Win( null, "myWindow", Elm.WinType.BASIC ); + win.title_set( "Elementary meets Vala" ); + win.autodel_set( true ); + win.resize( 320, 320 ); + win.smart_callback_add( "delete-request", this.quit ); + win.show(); + + layout = new Elm.Layout( win ); + layout.file_set( "/usr/local/share/elementary/objects/test.edj", "layout" ); + layout.size_hint_weight_set( 1.0, 1.0 ); + layout.show(); + win.resize_object_add( layout ); + } +} + +//======================================================================= +public static int main( string[] args ) +//======================================================================= +{ + var app = new DemoApplication( args ); + var res = app.run(); + if ( res >= 0 ) + debug( "app exit OK" ); + else + debug( "app exit with ERROR" ); + return res; +} + diff --git a/examples/vapi/main.vala b/examples/vapi/main.vala index b8c31e1..ad69328 100644 --- a/examples/vapi/main.vala +++ b/examples/vapi/main.vala @@ -17,16 +17,13 @@ * */ -using Evas; -using Elm; - -Win win; -Box box; -Button[] buttons; +Elm.Win win; +Elm.Box box; +Elm.Button[] buttons; public void add_test( T.Abstract t, int index ) { - buttons[index] = new Button( win ); + buttons[index] = new Elm.Button( win ); buttons[index].label_set( t.name() ); buttons[index].smart_callback_add( "clicked", t.run ); buttons[index].show(); @@ -38,13 +35,13 @@ public void add_test( T.Abstract t, int index ) public int main( string[] args ) { debug( "main()" ); - init( args ); + Elm.init( args ); - win = new Win( null, "myWindow", WinType.BASIC ); + win = new Elm.Win( null, "myWindow", Elm.WinType.BASIC ); win.title_set( "Elementary meets Vala" ); win.autodel_set( true ); win.resize( 320, 320 ); - win.smart_callback_add( "delete-request", exit ); + win.smart_callback_add( "delete-request", Elm.exit ); /* var bg = new Bg( win ); @@ -53,14 +50,14 @@ public int main( string[] args ) win.resize_object_add( bg ); */ - var layout = new Layout( win ); + var layout = new Elm.Layout( win ); layout.file_set( "/usr/local/share/elementary/objects/test.edj", "layout" ); layout.size_hint_weight_set( 1.0, 1.0 ); layout.show(); win.resize_object_add( layout ); - buttons = new Button[10]; - box = new Box( win ); + buttons = new Elm.Button[10]; + box = new Elm.Box( win ); box.size_hint_weight_set( 1.0, 1.0 ); win.resize_object_add( box ); @@ -73,7 +70,7 @@ public int main( string[] args ) box.show(); win.show(); - run(); - shutdown(); + Elm.run(); + Elm.shutdown(); return 0; } diff --git a/tests/.gitignore b/tests/.gitignore index c8ad6f3..ca07ed1 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -7,6 +7,6 @@ *.o testeina +testevas testecore testelementary - diff --git a/tests/Makefile.am b/tests/Makefile.am index 460d1c7..47ab73f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,6 +26,19 @@ testeina_LDADD = $(progs_ldadd) EXTRA_DIST += $(testeina_VALASOURCES) # +# evas +# +TEST_PROGS += testevas +testevas_VALASOURCES = testevas.vala +testevas_SOURCES = testevas.c testevas.h +$(testevas_SOURCES): $(testevas_VALASOURCES) + $(VALAC) -C --basedir $(top_srcdir) --vapidir $(top_srcdir)/vapi \ + --pkg eina --pkg evas --pkg glib-2.0 $^ + touch $@ +testevas_LDADD = $(progs_ldadd) +EXTRA_DIST += $(testevas_VALASOURCES) + +# # ecore # TEST_PROGS += testecore diff --git a/tests/testelementary.vala b/tests/testelementary.vala index baba457..99b89da 100644 --- a/tests/testelementary.vala +++ b/tests/testelementary.vala @@ -17,9 +17,6 @@ * */ -using Evas; -using Elm; - class Delegates : GLib.Object { public static void onDeleteStatic( Evas.Object o, void* event_info ) @@ -30,7 +27,7 @@ class Delegates : GLib.Object public void onDeleteMember( Evas.Object o, void* event_info ) { debug( "member callback" ); - exit(); + Elm.exit(); } public void onButtonClicked( Evas.Object b, void* event_info ) @@ -40,13 +37,23 @@ class Delegates : GLib.Object } } +public void test_objects() +{ + Elm.init( new string[] { "elementary_test" } ); + var win = new Elm.Win( null, "window", Elm.WinType.BASIC ); + var bg = new Elm.Bg( win ); + debug( "bg=%p, win=%p, parent(bg)=%p, parent(win)=%p", bg, win, bg.smart_parent_get(), win.smart_parent_get() ); + assert ( bg.smart_parent_get() == win ); + Elm.shutdown(); +} + public void test_mainloop() { string[] args = { "yo", "kurt" }; debug( "main()" ); - init( args ); - run(); - shutdown(); + Elm.init( args ); + Elm.run(); + Elm.shutdown(); } //=========================================================================== @@ -54,6 +61,7 @@ void main (string[] args) { Test.init(ref args); - Test.add_func("/MainLoop/All", test_mainloop); + Test.add_func( "/Objects", test_objects ); + Test.add_func( "/MainLoop/All", test_mainloop ); Test.run (); } diff --git a/eflvala/application.vala b/tests/testevas.vala similarity index 75% copy from eflvala/application.vala copy to tests/testevas.vala index d7b47f6..1e3c493 100644 --- a/eflvala/application.vala +++ b/tests/testevas.vala @@ -5,23 +5,30 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - **/ + */ -//======================================================================= -public class EflVala.Application : GLib.Object -//======================================================================= +public void test_objects() { - // owns and creates the two threads - // sets up the communication infrastructure - // contains methods to register for communication events + Evas.init(); + Evas.shutdown(); +} + +//=========================================================================== +void main (string[] args) +{ + Test.init(ref args); + + Test.add_func("/Objects", test_objects); + + Test.run (); } -- 2.11.4.GIT