example: adding a sample to show a simple case of callbacks with FFI
authorMatthieu Lucas <lucasmatthieu@gmail.com>
Tue, 30 Apr 2013 21:19:32 +0000 (17:19 -0400)
committerJean Privat <jean@pryen.org>
Wed, 1 May 2013 20:06:57 +0000 (16:06 -0400)
examples/README
examples/callback_chimpanze.nit [new file with mode: 0644]
examples/callback_monkey.nit [new file with mode: 0644]
tests/sav/callback_chimpanze.sav [new file with mode: 0644]
tests/sav/callback_monkey.sav [new file with mode: 0644]

index bd6e6b2..55f05bc 100644 (file)
@@ -7,4 +7,4 @@
 * clock_more.nit: refine clock to add comparability between clocks.
 * circular_list.nit: simple use of generic classes and nullable types to implement a double-linked circular list.
 * extern_methods.nit: basic use of extern methods, Nit methods implemented in C code
-
+* callback_monkey.nit|callback_chimpanze.nit: simple example of callback using through FFI.
diff --git a/examples/callback_chimpanze.nit b/examples/callback_chimpanze.nit
new file mode 100644 (file)
index 0000000..2ca8dc3
--- /dev/null
@@ -0,0 +1,45 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This sample has been implemented to show you how simple is it to play 
+# with native callbacks (C) through an high level with NIT program.
+
+module callback_chimpanze
+import callback_monkey
+
+class Chimpanze
+       super MonkeyActionCallable
+
+       fun create
+       do
+               var monkey = new Monkey
+               print "Hum, I'm sleeping ..."
+               # Invoking method which will take some time to compute, and 
+               # will be back in wokeUp method with information.
+               # - Callback method defined in MonkeyActionCallable Interface
+               monkey.wokeUpAction(self, "Hey, I'm awake.")
+       end
+
+       # Inherit callback method, defined by MonkeyActionCallable interface
+       # - Back of wokeUpAction method 
+       redef fun wokeUp( sender:Monkey, message:Object )
+       do
+               print message
+       end
+end
+
+var m = new Chimpanze
+m.create
diff --git a/examples/callback_monkey.nit b/examples/callback_monkey.nit
new file mode 100644 (file)
index 0000000..074df9f
--- /dev/null
@@ -0,0 +1,92 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This sample has been implemented to show you how simple is it to play 
+# with native callbacks (C) through an high level with NIT program.
+
+module callback_monkey
+
+in "C header" `{
+       #include <stdio.h>
+       #include <stdlib.h>
+
+       typedef struct { 
+               int id;
+               int age;
+       } CMonkey;
+
+       typedef struct {
+               MonkeyActionCallable toCall;
+               Object message;
+       } MonkeyAction;
+`}
+
+in "C body" `{
+       // Method which reproduce a callback answer
+       // Please note that a function pointer is only used to reproduce the callback
+       void cbMonkey(CMonkey *mkey, void callbackFunc(CMonkey*, MonkeyAction*), MonkeyAction *data)
+       {
+               sleep(2);
+               callbackFunc( mkey, data );
+       }
+
+       // Back of background treatment, will be redirected to callback function
+       void nit_monkey_callback_func( CMonkey *mkey, MonkeyAction *data )
+       {
+               // To call a your method, the signature must be written like this :
+               // <Interface Name>_<Method>...
+               MonkeyActionCallable_wokeUp( data->toCall, mkey, data->message );
+       }
+`}
+
+# Implementable interface to get callback in defined methods
+interface MonkeyActionCallable
+       fun wokeUp( sender:Monkey, message: Object) is abstract
+end
+
+# Defining my object type Monkey, which is, in a low level, a pointer to a C struct (CMonkey)
+extern Monkey `{ CMonkey * `}
+       
+       new `{
+               CMonkey *monkey = malloc( sizeof(CMonkey) );
+               monkey->age = 10;
+               monkey->id = 1;
+               return monkey;
+       `}
+       
+       # Object method which will get a callback in wokeUp method, defined in MonkeyActionCallable interface
+       # Must be defined as Nit/C method because of C call inside
+       fun wokeUpAction( toCall: MonkeyActionCallable, message: Object ) is extern import MonkeyActionCallable::wokeUp `{
+
+               // Allocating memory to keep reference of received parameters :
+               // - Object receiver
+               // - Message 
+               MonkeyAction *data = malloc( sizeof(MonkeyAction) );
+
+               // Incrementing reference counter to prevent from releasing
+               MonkeyActionCallable_incr_ref( toCall );
+               Object_incr_ref( message );
+               
+               data->toCall = toCall;
+               data->message = message;
+               
+               // Calling method which reproduce a callback by passing :
+               // - Receiver
+               // - Function pointer to object return method
+               // - Datas
+               cbMonkey( recv, &nit_monkey_callback_func, data );
+       `}
+end
diff --git a/tests/sav/callback_chimpanze.sav b/tests/sav/callback_chimpanze.sav
new file mode 100644 (file)
index 0000000..d677751
--- /dev/null
@@ -0,0 +1,2 @@
+Hum, I'm sleeping ...
+Hey, I'm awake.
diff --git a/tests/sav/callback_monkey.sav b/tests/sav/callback_monkey.sav
new file mode 100644 (file)
index 0000000..e69de29