Hello,
What I am trying to do is hold onto another PHP object in an internal
struct.
I.E:
<?php
$camera3d = new Camera3D();
$camera3d->position = new Vector3();
$camera3d->position->x++;
The reason for this is that the Camera3D struct has additional data I
need to track, so it cannot be an object of raw values.
// Vector3, 3 components
typedef struct Vector3 {
float x; // Vector x component
float y; // Vector y component
float z; // Vector z component
} Vector3;
// Camera, defines position/orientation in 3d space
typedef struct Camera3D {
Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees)
in perspective, used as near plane width in orthographic
int projection; // Camera projection: CAMERA_PERSPECTIVE or
CAMERA_ORTHOGRAPHIC
} Camera3D;
The idea is that when the $camera3d->position is modified, and when I
want to use the internal camera struct, I'll pull back the other PHP
object's internal values.
Right now it looks like this between Vector3 and Camera3D.
typedef struct _php_raylib_vector3_object {
Vector3 vector3;
HashTable *prop_handler;
zend_object std;
} php_raylib_vector3_object;
typedef struct _php_raylib_camera3d_object {
Camera3D camera3d;
HashTable *prop_handler;
php_raylib_vector3_object *position; // $camera3d->position
php_raylib_vector3_object *target; // $camera3d->target
php_raylib_vector3_object *up; // $camera3d->up
zend_object std;
} php_raylib_camera3d_object;
I've looked at the PHP LibXML extension, its using its own reference
counting, while SQLITE only uses efree() when deconstructing. The
general issue I am running into is that other values are being
assigned, or worst memory being corrupted, this crashing.
Its terms of the getting for the camera3d position object, I make sure
to add a gc ref when providing the object.
// If someone calls $camera3d->position
static zend_object *
php_raylib_camera3d_get_position(php_raylib_camera3d_object obj) /
{{{ /
{
GC_ADDREF(&obj->position->std);
return &obj->position->std;
}
/ }}} */
Then for the setter I delref and addref.
// If someone calls $camera3d->position = new Vector3d(1,2,3);
static int php_raylib_camera3d_set_position(php_raylib_camera3d_object
*obj, zval newval) / {{{ */
{
int ret = SUCCESS;
if (Z_TYPE_P(newval) == IS_NULL) {
// Cannot set this to null...
return ret;
}
php_raylib_vector3_object phpPosition = Z_VECTOR3_OBJ_P(newval);
GC_ADDREF(&phpPosition->std);
GC_DELREF(&obj->position->std);
obj->position = phpPosition;
obj->camera3d.position = phpPosition->vector3;
return ret;
}
/ }}} */
All is okay until when I need to update the internal Camera3D struct
via an update function called before it used:
// This takes the PHP objects of positon, target and up and assigns
those values back to the raw camera struct.
void php_raylib_camera3d_update_intern(php_raylib_camera3d_object *intern) {
intern->camera3d.position = intern->position->vector3; //
intern->position is php_raylib_vector3_object *
intern->camera3d.target = intern->target->vector3; //
intern->position is php_raylib_vector3_object *
intern->camera3d.up = intern->up->vector3; // intern->position is
php_raylib_vector3_object *
}
This works for the first time, but after creates an access error. Am I
missing something when tracking? When I need to provide a PHP object I
assumed I need to GC_ADDREF and the same was when replaced GC_DELREF.
But when it's initialized or accessed internally do I need to continue
to use those macros? I looked like LibXML as it has a similar concept
but it's manually tracked references. SQLite3 also does something
similar but only calls efree() when the root object is freed.
I have the code available for how it's constructed.
https://github.com/joseph-montanez/raylib-php/blob/develop/camera3d.c
Thanks,
Joseph Montanez
Thanks,
Joseph Montanez