[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-smalltalk] Gtk event loop
From: |
Paolo Bonzini |
Subject: |
Re: [Help-smalltalk] Gtk event loop |
Date: |
Tue, 16 Feb 2010 17:33:46 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100120 Fedora/3.0.1-1.fc12 Lightning/1.0b2pre Thunderbird/3.0.1 |
Despite the apparent harshness of the review, it's really good stuff.
Thanks!
Go through the comments in the order I mention (see asterisked numbers;
each number refers to the text before) and commit the solution to each
part (which may not be exactly what I write of course!) separately so
it's easy to understand when things wrong.
So let's start... first: where is the ChangeLog? :-)
+ handleInnerEvent [
+
+ | event |
+ event := GTK.Gtk events.
+ event ifNotNil: [ | args |
+ args := Array new: event n_params value.
+ 1 to: args size do: [ :i | args at: i put: (event data value at: i
- 1) ].
+ [ ^ (event receiver value perform: event selector value
withArguments: args) ] on: Exception do: [ :exception |
+ Behavior debuggerClass open ] ]
+ ]
Why the handler? It shouldn't be necessary as the inner event runs in
its own Smalltalk process. *10*
+ insideLoop [
+
+ | event |
+ eventSem wait.
+ event := GTK.Gtk events.
+ event ifNotNil: [ | args |
+ args := Array new: event n_params value.
+ 1 to: args size do: [ :i | args at: i put: (event data value at: i
- 1) ].
+ [ GTK.Gtk result: (event receiver value perform: event selector
value withArguments: args) mutex: event mutex value ] on: Exception do: [
:exception |
+ event status value: 0.
+ Behavior debuggerClass open.
+ GTK.Gtk result: nil mutex: event mutex value ] ]
What about something like this instead, trapping Exception is almost
always wrong (you trap Notification and Warning as well):
[ [ result := event receiver value perform: event selector value
withArguments: args ]
on: System.UnhandledException do: [ :ex |
event status value: 0.
ex pass ] ]
ensure: [ GTK.Gtk result: result mutex: event mutex value ]
*11*
- sem := Semaphore new.
- GTK.Gtk main: sem.
+ eventSem:= Semaphore new.
+ GTK.Gtk eventSemaphore: eventSem.
+ GTK.Gtk mainLoop.
+ [ self insideLoop.
What about instead keeping more of the old code: *3*
sem := Semaphore new.
GTK.Gtk mainLoop: sem.
[ self insideLoop: sem
?
(BTW I'd rename insideLoop to #processEvents or something like that). *2*
+ true ] whileTrue: [ "DOES NOT WORK :::::: Processor yield" ]
Is it needed at all, since we yield when waiting on sem? *1* Just do
[ self insideLoop ] repeat
(or the similar thing with sem if you accept my suggestion above).
diff --git a/packages/gtk/MoreFuncs.st b/packages/gtk/MoreFuncs.st
index a07ae29..d16210d 100644
--- a/packages/gtk/MoreFuncs.st
+++ b/packages/gtk/MoreFuncs.st
@@ -12,9 +12,9 @@ Gtk class extend [
]
- main: aSemaphore [
+ mainLoop [
<category: 'C call-outs'>
- <asyncCCall: 'gstGtkMain' args: #(#smalltalk )>
+ <asyncCCall: 'gstGtkMain' args: #()>
Doesn't need to be asynchronous anymore. In fact, I'd like to deprecate
#asyncCCall:, I'm not even sure I understand their implications.
Just make it return void. *4*
+static OOP result = NULL;
This is never read?!?
Also, maybe you want to move it to SmalltalkClosureStruct. *5*
+typedef struct SmalltalkClosureStruct {
+ OOP receiver;
+ OOP selector;
+ OOP *data;
+ OOP widget;
+ int n_params;
+ GMutex *mutex;
+ int status
+} SmalltalkClosureStruct;
+
+static SmalltalkClosureStruct *event;
Does not need to be static. *6*
-static void my_gtk_main (OOP semaphore);
+static void my_gtk_main ();
As above, consider keeping the parameter. *3*
+ event = malloc (sizeof (*event));
Nowhere freed. *7*
+ event->receiver = stc->receiver;
+ event->selector = stc->selector;
registerOOP on these and args. Even better, construct a DirectedMessage
object so that #insideLoop and #handleInnerEvent can just do "event
message value send". Right now they have duplicated code! *7*
+ if (g_thread_self () != main_thread) {
g_thread_equal. *8*
+ event->mutex = g_mutex_new ();
+ g_mutex_lock (event->mutex);
+
+ _gst_vm_proxy->syncSignal (event_sem, true);
+ _gst_vm_proxy->wakeUp ();
+
+ g_mutex_lock (event->mutex);
Locking twice is surely wrong? *9*
+ // Smalltalk event handling raises an exception launch an inner
+ // event loop
+ //
+ if (event->status == 0)
+ gtk_main ();
Longer longer longer explanation needed? (And no // comments). Actually,
let's postpone this to after the next iteration.
+void
+set_event_semaphore (OOP semaphore)
+{
+ event_sem = semaphore;
+ _gst_vm_proxy->registerOOP (semaphore);
+}
Unnecessary if you pass the semaphore to my_gtk_main. *3*
+void
+set_result (OOP anObject, GMutex *mutex)
+{
+ result = anObject;
+ g_mutex_unlock (mutex);
+}
Pass back the entire events struct so that you can also call
unregisterOOP, free the args, and free the struct itself. If you make
it like this:
void
set_event_result (SmalltalkClosureStruct *event, OOP anObject)
{
event->result = anObject;
g_mutex_unlock (event->mutex);
}
you can even declare it as an instance-side method in
SmalltalkClosureStruct. Much nicer that way! *5*
- self
+ "self
connectSignal: 'paste-clipboard' to: self selector: #paste
userData: nil;
connectSignal: 'cut-clipboard' to: self selector: #cut userData:
nil.
@@ -24,7 +24,7 @@ GTK.GtkTextView subclass: GtkTextWidget [
connectSignal: 'begin-user-action' to: self selector:
#'beginUserAction' userData: nil;
connectSignal: 'end-user-action' to: self selector:
#'endUserAction' userData: nil;
connectSignal: 'insert-text' to: self selector:
#'insert:at:text:size:' userData: nil;
- connectSignal: 'delete-range' to: self selector:
#'delete:from:to:' userData: nil
+ connectSignal: 'delete-range' to: self selector: #'delete:from:to:'
userData: nil"
What's the problem? Things like this should not be there for the new
event loop to go in.
@@ -218,10 +221,7 @@ THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.';
<category: 'file events'>
(GTK.GtkFileChooserDialog save: 'Save image as...' parent: window)
- runNonBlockingAndDo: [ :dlg :res |
- imageName := dlg getFilename.
- dlg destroy.
- res = GTK.Gtk gtkResponseAccept ifTrue: [ self saveImage: [
ObjectMemory snapshot: imageName ] ] ]
+ run
Same here of course.
-<start>VisualGST.VisualGST open.
- GTK.Gtk main</start>
+<start>
+ | a |
+ VisualGST.VisualGST open.
+ [ GTK.Gtk main ] fork.
+ a := Semaphore new.
+ a wait.
+ 'byebye' printNl.
+</start>
This is just debugging code I guess?
Paolo
- [Help-smalltalk] Gtk event loop, Gwenael Casaccio, 2010/02/11
- Re: [Help-smalltalk] Gtk event loop, Paolo Bonzini, 2010/02/11
- Re: [Help-smalltalk] Gtk event loop, Gwenael Casaccio, 2010/02/12
- Re: [Help-smalltalk] Gtk event loop, Paolo Bonzini, 2010/02/12
- Re: [Help-smalltalk] Gtk event loop, Gwenael Casaccio, 2010/02/16
- Re: [Help-smalltalk] Gtk event loop, Gwenael Casaccio, 2010/02/16
- Re: [Help-smalltalk] Gtk event loop, Paolo Bonzini, 2010/02/16
- [Help-smalltalk] Re: Gtk event loop, Paolo Bonzini, 2010/02/16
- Re: [Help-smalltalk] Gtk event loop,
Paolo Bonzini <=
- [Help-smalltalk] Re: Gtk event loop, Paolo Bonzini, 2010/02/16