0
我想在運行超時動畫的時候在vala/clutter中加載圖像文件,使用「image.set_load_async」在請求文件加載時停止一段時間的動畫。這是源:Vala/Clutter紋理加載線程
// valac --thread --pkg clutter-1.0 --pkg=gio-2.0 test_1.vala -o test_1
using Clutter;
class SlideImage : Clutter.Actor {
protected Texture image = new Texture();
public int loaded = 0;
public SlideImage (string file) {
try {
loaded = 1;
image.set_load_async (true);
image.load_finished.connect((t, a) => {
loaded = 2;
this.add_actor (image);
});
image.set_from_file (file);
} catch (Error e) {
warning("Error setting SlideImageReflected gradient : %s", e.message);
}
}
}
class ClutterSlideShow {
protected Stage stage;
protected int width = 800;
protected int height =700;
protected string[] file_names = {};
private int file_pointer = 0;
private int counter = 0;
private SlideImage showA = null;
private SlideImage showB = null;
private SlideImage showC = null;
private SlideImage showD = null;
private SlideImage showE = null;
public ClutterSlideShow (string folder) {
try {
var directory = File.new_for_path (folder);
var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME,0);
FileInfo file_info;
while ((file_info = enumerator.next_file()) != null) {
file_names += folder+"/"+file_info.get_name();
}
} catch (Error e) {
stderr.printf ("Error ClutterSlideShow listing files: %s\n", e.message);
}
stage = Stage.get_default();
stage.hide.connect (Clutter.main_quit);
stage.color = Color() { red = 0, green = 0, blue = 0, alpha = 255 };;
stage.set_size (width, height);
stage.show_all();
}
protected string get_next_file() {
file_pointer++;
if (file_pointer > file_names.length) file_pointer = 1;
return file_names[file_pointer-1];
}
public void start() {
Timeout.add (15, run);
}
private bool run() {
if (showA == null) {
showA = new SlideImage (get_next_file());
showA.set_x (0);
showA.set_y (0);
} else if (showA.loaded == 2) {
stage.add_actor (showA);
showA.loaded = 3;
} else if (showA.loaded == 3) {
showA.set_y (showA.get_y() + 1);
counter++;
if (counter==100) {
showB = new SlideImage (get_next_file());
showB.set_x (100);
showB.set_y (0);
stage.add_actor (showB);
showC = new SlideImage (get_next_file());
showC.set_x (200);
showC.set_y (0);
stage.add_actor (showC);
showD = new SlideImage (get_next_file());
showD.set_x (300);
showD.set_y (0);
stage.add_actor (showD);
showE = new SlideImage (get_next_file());
showE.set_x (400);
showE.set_y (0);
stage.add_actor (showE);
}
}
return true;
}
}
int main (string[] args) {
if (Thread.supported() == false) {
stderr.printf ("Threads are not supported!\n");
return -1;
}
var result = init (ref args);
if (result != Clutter.InitError.SUCCESS) {
stderr.printf("Error: %s\n", result.to_string());
return 1;
}
var slide_show = new ClutterSlideShow ("/usr/share/backgrounds/");
slide_show.start();
Clutter.main();
return 0;
}
我也嘗試使用「線程」但我得到一個「分段故障(核心轉儲)」,我不知道如何調試或修復。這是例如:
// valac --thread --pkg clutter-1.0 --pkg=gio-2.0 test_2.vala -o test_2
using Clutter;
class SlideImage : Clutter.Actor {
protected Texture image = new Texture();
public int loaded = 0;
public SlideImage (string file) {
loaded = 1;
load_image_in_background.begin(file, (obj, res) => {
try {
loaded = 2;
this.add_actor (image);
} catch (ThreadError e) {
string msg = e.message;
stderr.printf(@"Thread error: $msg\n");
}
});
}
async void load_image_in_background (string file) throws ThreadError {
SourceFunc callback = load_image_in_background.callback;
ThreadFunc<void*> run =() => {
try {
// Help ! The next line results in "Segmentation fault"
image.set_from_file (file);
} catch (Error e) {
warning("Error setting SlideImage texture : %s", e.message);
}
Idle.add((owned) callback);
return null;
};
Thread.create<void*>(run, false);
yield;
}
}
class ClutterSlideShow {
protected Stage stage;
protected int width = 800;
protected int height =700;
protected string[] file_names = {};
private int file_pointer = 0;
private int counter = 0;
private SlideImage showA = null;
private SlideImage showB = null;
private SlideImage showC = null;
private SlideImage showD = null;
private SlideImage showE = null;
public ClutterSlideShow (string folder) {
try {
var directory = File.new_for_path (folder);
var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME,0);
FileInfo file_info;
while ((file_info = enumerator.next_file()) != null) {
file_names += folder+"/"+file_info.get_name();
}
} catch (Error e) {
stderr.printf ("Error ClutterSlideShow listing files: %s\n", e.message);
}
stage = Stage.get_default();
stage.hide.connect (Clutter.main_quit);
stage.color = Color() { red = 0, green = 0, blue = 0, alpha = 255 };;
stage.set_size (width, height);
stage.show_all();
}
protected string get_next_file() {
file_pointer++;
if (file_pointer > file_names.length) file_pointer = 1;
return file_names[file_pointer-1];
}
public void start() {
Timeout.add (15, run);
}
private bool run() {
if (showA == null) {
showA = new SlideImage (get_next_file());
showA.set_x (0);
showA.set_y (0);
} else if (showA.loaded == 2) {
stage.add_actor (showA);
showA.loaded = 3;
} else if (showA.loaded == 3) {
showA.set_y (showA.get_y() + 1);
counter++;
if (counter==100) {
showB = new SlideImage (get_next_file());
showB.set_x (100);
showB.set_y (0);
stage.add_actor (showB);
showC = new SlideImage (get_next_file());
showC.set_x (200);
showC.set_y (0);
stage.add_actor (showC);
showD = new SlideImage (get_next_file());
showD.set_x (300);
showD.set_y (0);
stage.add_actor (showD);
showE = new SlideImage (get_next_file());
showE.set_x (400);
showE.set_y (0);
stage.add_actor (showE);
}
}
return true;
}
}
int main (string[] args) {
if (Thread.supported() == false) {
stderr.printf ("Threads are not supported!\n");
return -1;
}
var result = init (ref args);
if (result != Clutter.InitError.SUCCESS) {
stderr.printf("Error: %s\n", result.to_string());
return 1;
}
var slide_show = new ClutterSlideShow ("/usr/share/backgrounds/");
slide_show.start();
Clutter.main();
return 0;
}
只是一個穿線評論:它很少需要油嘴/ GTK +,並且使用線程往往是難以調試問題的途徑......加載圖像也不例外,請參閱http://stackoverflow.com/questions/10831889瞭解異步圖像加載的一個示例。 – jku