Skip to content

Commit

Permalink
initial implementation of Signal class
Browse files Browse the repository at this point in the history
  • Loading branch information
indeyets committed Jul 26, 2010
1 parent a6ab3ad commit 071a91f
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 2 deletions.
2 changes: 1 addition & 1 deletion config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ if test "$PHP_GOBJECT" != "no"; then
AC_DEFINE(HAVE_GOBJECT, 1, [ ])

PHP_NEW_EXTENSION(gobject, \
gobject_ext.c gobject_helpers.c gobject_paramspec_class.c gobject_type_class.c gobject_gobject_class.c gobject_closure.c \
gobject_ext.c gobject_helpers.c gobject_paramspec_class.c gobject_type_class.c gobject_gobject_class.c gobject_closure.c gobject_signal_class.c \
, $ext_shared)

EXT_GOBJECT_HEADERS="php_gobject.h"
Expand Down
2 changes: 1 addition & 1 deletion config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ ARG_WITH("gobject", "GObject Library Bindings", "no");
if (PHP_GLIB != "no") {
CHECK_LIB("gobject-2.0.lib", "gobject", PHP_GOBJECT);
CHECK_HEADER_ADD_INCLUDE("gobject_ext.h", "CFLAGS_GOBJECT", null, null, true);
EXTENSION("gobject", "gobject_ext.c gobject_helpers.c gobject_paramspec_class.c gobject_type_class.c gobject_gobject_class.c gobject_closure.c");
EXTENSION("gobject", "gobject_ext.c gobject_helpers.c gobject_paramspec_class.c gobject_type_class.c gobject_gobject_class.c gobject_closure.c gobject_signal_class.c");
AC_DEFINE("HAVE_GOBJECT", 1);
}
2 changes: 2 additions & 0 deletions gobject_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ PHP_MINIT_FUNCTION(gobject)
PHP_MINIT(gobject_type)(INIT_FUNC_ARGS_PASSTHRU);
PHP_MINIT(gobject_gobject)(INIT_FUNC_ARGS_PASSTHRU);
PHP_MINIT(gobject_closure)(INIT_FUNC_ARGS_PASSTHRU);
PHP_MINIT(gobject_signal)(INIT_FUNC_ARGS_PASSTHRU);

return SUCCESS;
}
Expand All @@ -108,6 +109,7 @@ PHP_MSHUTDOWN_FUNCTION(gobject)
*/
PHP_MSHUTDOWN_FUNCTION(gobject_gobject);
PHP_MSHUTDOWN_FUNCTION(gobject_type);
PHP_MSHUTDOWN_FUNCTION(gobject_signal);

return SUCCESS;
}
Expand Down
219 changes: 219 additions & 0 deletions gobject_signal_class.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Alexey Zakhlestin <indeyets@php.net> |
+----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <php.h>
#include <zend_interfaces.h>
#include <zend_exceptions.h>

#include <ext/spl/spl_array.h>
#include <ext/spl/spl_exceptions.h>

#include "php_gobject.h"

zend_class_entry *gobject_ce_signal;
static zend_object_handlers *php_gobject_signal_handlers;

void gobject_signal_free_storage(gobject_signal_object *intern TSRMLS_DC)
{
if (intern->std.guards) {
zend_hash_destroy(intern->std.guards);
FREE_HASHTABLE(intern->std.guards);
}

if (intern->std.properties) {
zend_hash_destroy(intern->std.properties);
FREE_HASHTABLE(intern->std.properties);
}

if (intern->param_types) {
zval_ptr_dtor(&intern->param_types);
}

if (intern->class_closure_fci.function_name) {
zval_ptr_dtor(&(intern->class_closure_fci.function_name));
}

if (intern->accumulator_fci.function_name) {
zval_ptr_dtor(&(intern->accumulator_fci.function_name));
}

efree(intern);
}

zend_object_value gobject_signal_object_new(zend_class_entry *ce TSRMLS_DC)
{
zend_object_value retval;
gobject_signal_object *object;

object = emalloc(sizeof(gobject_signal_object));
object->std.ce = ce;
object->std.guards = NULL;

ALLOC_HASHTABLE(object->std.properties);
zend_hash_init(object->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);

zval *tmp;
zend_hash_copy(
object->std.properties,
&ce->default_properties,
(copy_ctor_func_t) zval_add_ref,
(void *) &tmp,
sizeof(zval *)
);

object->flags = 0;
object->param_types = NULL;
object->return_type = 0;
object->class_closure_fci = empty_fcall_info;
object->class_closure_fci_cache = empty_fcall_info_cache;
object->accumulator_fci = empty_fcall_info;
object->accumulator_fci_cache = empty_fcall_info_cache;

retval.handle = zend_objects_store_put(
object,
(zend_objects_store_dtor_t)zend_objects_destroy_object,
(zend_objects_free_object_storage_t) gobject_signal_free_storage,
NULL
TSRMLS_CC
);
retval.handlers = php_gobject_signal_handlers;

return retval;
}

zval *php_gobject_signal_read_property(zval *zobject, zval *prop, int type TSRMLS_DC)
{
const char *propname = Z_STRVAL_P(prop);
int proplen = Z_STRLEN_P(prop);

gobject_signal_object *object = (gobject_signal_object *)zend_objects_get_address(zobject TSRMLS_CC);

if ( proplen == 5 && strncmp(propname, "flags", 5) == 0) {
zval *retval;
MAKE_STD_ZVAL(retval);
ZVAL_LONG(retval, object->flags);
Z_DELREF_P(retval); // setting refcount to 0. receiving side is responsible for adding ref

return retval;
} else {
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "No way to get this property");
return NULL;
}
}

void php_gobject_signal_write_property(zval *zobject, zval *prop, zval *value TSRMLS_DC)
{
const char *propname = Z_STRVAL_P(prop);
int proplen = Z_STRLEN_P(prop);

gobject_signal_object *object = (gobject_signal_object *)zend_objects_get_address(zobject TSRMLS_CC);

if (proplen == 5 && strncmp(propname, "flags", 5) == 0) {
convert_to_long(value);
object->flags = Z_LVAL_P(value);
} else {
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "No way to set this property");
}
}

zval **php_gobject_signal_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC)
{
// we don't want to provide direct access to underlying properties
return NULL;
}


ZEND_BEGIN_ARG_INFO_EX(arginfo_Glib_GObject_Signal___construct, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
ZEND_ARG_INFO(0, flags)
ZEND_ARG_INFO(0, param_types)
ZEND_ARG_INFO(0, return_type)
ZEND_ARG_INFO(0, class_closure)
ZEND_ARG_INFO(0, accumulator)
ZEND_END_ARG_INFO()

PHP_METHOD(Glib_GObject_Signal, __construct)
{
long flags = 0;
zval *param_types = NULL;
char *return_type = NULL;
int return_type_len = 0;
zend_fcall_info cc_fci = empty_fcall_info, acc_fci = empty_fcall_info;
zend_fcall_info_cache cc_fci_cache = empty_fcall_info_cache, acc_fci_cache = empty_fcall_info_cache;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lzsff", &flags, &param_types, &return_type, &return_type_len,
&cc_fci, &cc_fci_cache, &acc_fci, &acc_fci_cache
) == FAILURE
) {
return;
}

gobject_signal_object *object = (gobject_signal_object *)zend_objects_get_address(getThis() TSRMLS_CC);
object->flags = flags;
object->param_types = param_types;
object->class_closure_fci = cc_fci;
object->class_closure_fci_cache = cc_fci_cache;
object->accumulator_fci = acc_fci;
object->accumulator_fci_cache = acc_fci_cache;

if (return_type) {
GType new_gtype = g_type_from_name(return_type);

if (0 == new_gtype) {
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "This class is not registered: %s", return_type);
return;
}

object->return_type = new_gtype;
}
}


const zend_function_entry gobject_signal_methods[] = {
// public
PHP_ME(Glib_GObject_Signal, __construct, arginfo_Glib_GObject_Signal___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
{NULL, NULL, NULL}
};

PHP_MINIT_FUNCTION(gobject_signal)
{
zend_class_entry ce;

INIT_NS_CLASS_ENTRY(ce, GOBJECT_NAMESPACE, "Signal", gobject_signal_methods);
gobject_ce_signal = zend_register_internal_class(&ce TSRMLS_CC);
gobject_ce_signal->create_object = gobject_signal_object_new;

// standard handlers + overriding
php_gobject_signal_handlers = malloc(sizeof(zend_object_handlers));
memcpy(php_gobject_signal_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
php_gobject_signal_handlers->write_property = php_gobject_signal_write_property;
php_gobject_signal_handlers->read_property = php_gobject_signal_read_property;
php_gobject_signal_handlers->get_property_ptr_ptr = php_gobject_signal_get_property_ptr_ptr;

return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(gobject_signal)
{
free(php_gobject_signal_handlers);

return SUCCESS;
}
14 changes: 14 additions & 0 deletions php_gobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ typedef struct _gobject_type_object {
zend_bool is_registered;
} gobject_type_object;

typedef struct _gobject_signal_object {
zend_object std;
GSignalFlags flags;
zval *param_types; // array
GType return_type;
zend_fcall_info class_closure_fci;
zend_fcall_info_cache class_closure_fci_cache;
zend_fcall_info accumulator_fci;
zend_fcall_info_cache accumulator_fci_cache;
} gobject_signal_object;

typedef struct _gobject_gobject_object {
zend_object std;
GObject *gobject;
Expand Down Expand Up @@ -89,10 +100,13 @@ PHP_MINIT_FUNCTION(gobject_type);
PHP_MINIT_FUNCTION(gobject_gobject);
PHP_RINIT_FUNCTION(gobject_gobject);
PHP_MINIT_FUNCTION(gobject_closure);
PHP_MINIT_FUNCTION(gobject_signal);

// component shutdown
PHP_MSHUTDOWN_FUNCTION(gobject_type);
PHP_MSHUTDOWN_FUNCTION(gobject_gobject);
PHP_MSHUTDOWN_FUNCTION(gobject_signal);

PHP_RSHUTDOWN_FUNCTION(gobject_gobject);

// api
Expand Down

0 comments on commit 071a91f

Please sign in to comment.