The `Task` interface defines a fragment of Nit code to execute in its `main` method. This interface should be compatible between different platforms and parallelization engines.
`NativeActivity::run_on_ui_thread` is widely used on Android as most logic is executed on background threads but only the UI thread can modify the UI. It is a perfect example of how the `Task` interface can be used.
Future work include using `Task` in `pthreads` and `gtk::gdk`. But there a a few differences in the logic that makes it not as easy: `Thread::main` returns a `nullable object`, but is it worth keeping it? `GdkRunnable::run` returns a boolean to tell GDK if it should be called again.
Pull-Request: #1812
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Romain Chanoir <romain.chanoir@viacesi.fr>
end
# All tasks to be performed
- var tasks = new Array[Task]
+ var tasks = new Array[TesterTask]
# Gather and register all tasks
fun create_tasks
continue label
end
- tasks.add new Task(engine, prog)
+ tasks.add new TesterTask(engine, prog)
end label
end
end
# Single C `int` to hold the next task id received from the `Controller`
var task_buffer = new CIntArray(1)
- # Manage communication with the `Controller` and execute dispatched `Task`s
+ # Manage communication with the `Controller` and execute dispatched `TesterTask`s
fun work_on_tasks
do
var status = new Status
#
# Note that a task may involve more than one program to test considering the
# alts and args for the `test_program`.
-class Task
+class TesterTask
# Engine to test executing `test_program`
var engine: String
redef fun to_s do return "{engine} {test_program}"
end
-# Result of a `Task`
+# Result of a `TesterTask`
#
-# There may be more than one result per `Task`.
+# There may be more than one result per `TesterTask`.
class Result
- # `Task` associated to `self`
- var task: Task
+ # `TesterTask` associated to `self`
+ var task: TesterTask
# Argument index of the execution resulting in `self`
var arg: Int
# Notify the OS that this activity is done and should be closed
fun finish in "Java" `{ self.finish(); `}
+
+ # Execute `task.main` on the UI thread when possible
+ fun run_on_ui_thread(task: Task) import Task.main in "Java" `{
+ final int final_task = task;
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ Task_main(final_task);
+ }
+ };
+ self.runOnUiThread(runnable);
+ `}
end
# Free the memory pointed by this pointer
fun free `{ free(self); `}
end
+
+# Task with a `main` method to be implemented by subclasses
+#
+# This class is provided for compatibility between different parallelization systems.
+# It can be used to run a fragment of code on a different thread and
+# to register a reaction to UI events.
+interface Task
+
+ # Main method of this task
+ fun main do end
+end
../lib/core/kernel.nit:704,1--890,3: Error: `kernel#Int` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:892,1--1060,3: Error: `kernel#Char` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
../lib/core/kernel.nit:1062,1--1069,3: Error: `kernel#Pointer` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
+../lib/core/kernel.nit:1071,1--1080,3: Error: `kernel#Task` does not specialize `module_0#Object`. Possible duplication of the root class `Object`?
]
Object -> Pointer [dir=back arrowtail=open style=dashed];
+Task [
+ label = "{interface\nTask||+ main()\l}"
+]
+Object -> Task [dir=back arrowtail=open style=dashed];
+
A [
label = "{A|- _vpubA: nullable A\l- _vproA: nullable A\l- _vpriA: nullable A\l- _vpubA2: A\l- _vproA2: A\l- _vpriA2: A\l- _vpriB: nullable B\l- _vpriB2: B\l|+ pubA(a: A)\l# proA(a: A)\l- priA(a: A)\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l# vproA(): nullable A\l# vproA=(vproA: nullable A)\l- vpriA(): nullable A\l- vpriA=(vpriA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l# vproA2(): A\l# vproA2=(vproA2: A)\l- vpriA2(): A\l- vpriA2=(vpriA2: A)\l- priB(a: B)\l- vpriB(): nullable B\l- vpriB=(vpriB: nullable B)\l- vpriB2(): B\l- vpriB2=(vpriB2: B)\l}"
]
]
Object -> Pointer [dir=back arrowtail=open style=dashed];
+Task [
+ label = "{interface\nTask||+ main()\l}"
+]
+Object -> Task [dir=back arrowtail=open style=dashed];
+
A [
label = "{A||+ pubA(a: A)\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l}"
]