All pastes #933953 Raw Edit

Generators in Vala, an attempt,

public text v1 · immutable
·published 2008-03-08 15:42 UTC
rendered paste body
using GLib;

class Generator<T>
{
	private weak Thread thread;
	private Mutex mutex;
	private Cond cond_avail;

	private T yielded;
	private bool has_data;
	public delegate void Func(Generator gen);
	private Func func;

	public void* thread_func()
	{
		func(this);
		mutex.lock();
		func = null;
		cond_avail.signal();
		mutex.unlock();
		return null;
	}

	public void yield(T data)
	{
		mutex.lock();

		while(has_data)
			cond_avail.wait(mutex);

		yielded = data;
		has_data = true;

		cond_avail.signal();
		mutex.unlock();
	}

	public bool next(ref T value)
	{
		bool running;
		mutex.lock();

		while(!has_data && func != null)
			cond_avail.wait(mutex);

		if(!has_data && func == null)
			running = false;
		else
		{
			running = true;
			value = yielded;
			has_data = false;
			cond_avail.signal();
		}

		mutex.unlock();
		return running;
	}

	public Generator (Func genfunc)
	{
		if (!Thread.supported ())
			Thread.init ();

		func = genfunc;
		cond_avail = new Cond ();
		mutex = new Mutex ();
		has_data = false;
	}
	
	public void start()
	{
		thread = Thread.create (thread_func, false);
	}
}


class Test
{
	static void generate(Generator gen)
	{
		int[] values = new int [] {100, 200, 300, 400, 500, 0};
		int i;

		for(i=0; values[i] != 0; i++)
		{
			gen.yield(values[i]);
			Thread.usleep(500000);
		}
	}

	static void main(string[] args)
	{
		Generator gen = new Generator(generate);
		gen.start();
		int value;
		while(gen.next(ref value))
		{
			stdout.printf("Value = %d\n", value);
		}
	}
}