[Vala] Treating a uint as a reference type?



Hi Vala World,

I was wondering if it's possible to implement a Vala class as a C-side
guint, but have Vala emit calls to a ref and unref function, and to treat a
C-side 0 as a Vala-side null.

Basically I want to make something like this:

// Vala
static
Entity? mine = null;

static
void
set_mine(owned Entity e) {
  mine = (owned) e;
}

static
void
do_stuff() {
  Entity e = Entity.create();
  set_mine(e);
}

And get it compiled to C:

/* C */
guint mine = NULL;
void
set_mine(guint e) {
  if (mine != NULL) entity_unref(mine);
  mine = e;
}

void
do_stuff() {
  guint e = entity_create();
  set_mine(entity_ref(e));
}

So far, I've tried using a [Compact][CCode (cname="guint")] class, but that
is passed around as a guint* and Vala feels obliged to add a "typedef
struct _guint guint". which fails since guint is already defined as
unsigned int.

I've also tried using a [CCode (cname="guint")] extern struct, but that
causes any ref_function and unref_function attributes to be ignored, and
still adds "typedef struct _guint guint".

Is it possible to have Vala remove the "*" in reference types and still
have it use ref/unref functions and have it remove typedef?

--

I'm trying to make an Entity Component System, and ensure that destroyed
entities are not reused until all references to them are destroyed.
Entities are normally implemented as simple integer ID's, which are
semantically a pointer to a row of component slots.

My current design has each attached component add a reference to the
entity, and the entity manager also adds a reference; when an entity is
destroyed, the entity manager detaches all components (which cause each
component to drop the reference) and drops its own reference; this frees
the entity unless another reference is kept elsewhere.  If a reference to
an entity is kept elsewhere, it can then be queried as to whether it has
been destroyed without worrying that its ID has been re-allocated to a
freshly-made entity (for instance, consider a missile locked on to some
game entity; if the target dies, we want the missile to know it has no
longer any valid target, not have it suddenly chase another entity that
happened to get allocated the same ID as the missile's original target in a
different subsystem).

In my current design entities are compact classes with an ID and a refcount
and custom ref_function and unref_function, and freed entities are retained
in a freelist to reuse the ID.  I was wondering if I could make entities
just the ID itself, and store the refcount in a separate array.

I could possibly live with passing around Entity*, and use (guintptr) to
extract the ID from the pointer, but I worry since C does not guarantee
that a pointer can retain all possible guintptr values.  guintptr can hold
any pointer type, but a pointer type is not necessarily capable of holding
any guintptr.

Sincerely,
AmkG


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]