我试图在运行超时动画时在 vala/clutter 中加载图像文件,当请求文件加载时,使用“image.set_load_async”会停止动画一段时间。这是来源:
// 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;
}