/* * $Id: rb_idler.c 351 2006-02-10 15:25:40Z tilman $ * * Copyright (C) 2004 ruby-ecore team (see AUTHORS) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "rb_ecore.h" typedef struct { Ecore_Idler *real; VALUE callback; bool deleted; } RbIdler; static int on_idler (void *data) { VALUE r; RbIdler *idler = data; r = rb_funcall (idler->callback, rb_intern ("call"), 0); /* if the callback returns false, we return 0 and Ecore * will remove the idler */ if (r == Qfalse) idler->deleted = true; return (r != Qfalse); } static void c_mark (RbIdler *idler) { rb_gc_mark (idler->callback); } static void c_free (RbIdler *idler) { if (idler->real && !idler->deleted) ecore_idler_del (idler->real); ecore_shutdown (); free (idler); } static VALUE c_alloc (VALUE klass) { RbIdler *idler; ecore_init (); return Data_Make_Struct (klass, RbIdler, c_mark, c_free, idler); } /* * call-seq: * Ecore::Idler.new { block } => idler * * Creates an Ecore::Idler object. * When Ecore is idle, the specified block will be called. * If the block returns false, the idler is deleted. */ static VALUE c_init (VALUE self) { GET_OBJ (self, RbIdler, idler); if (!rb_block_given_p ()) rb_raise (rb_eStandardError, "block missing"); idler->callback = rb_block_proc (); idler->deleted = false; idler->real = ecore_idler_add (on_idler, idler); return self; } /* * call-seq: * idler.delete => nil * * Deletes idler. */ static VALUE c_delete (VALUE self) { GET_OBJ (self, RbIdler, idler); if (idler->real && !idler->deleted) { ecore_idler_del (idler->real); idler->real = NULL; idler->deleted = true; } else rb_raise (rb_eException, "Idler already deleted!"); return Qnil; } void Init_Idler (void) { VALUE c = rb_define_class_under (mEcore, "Idler", rb_cObject); rb_define_alloc_func (c, c_alloc); rb_define_method (c, "initialize", c_init, 0); rb_define_method (c, "delete", c_delete, 0); }