Implement object broker mechanism.
authorGuo Rui <firemeteor@Adam.(none)>
Thu, 16 Jul 2009 16:14:50 +0000 (17 00:14 +0800)
committerGuo Rui <firemeteor@Adam.(none)>
Thu, 16 Jul 2009 16:14:50 +0000 (17 00:14 +0800)
src/script.c
src/script.h

index b123d06..ce035cb 100644 (file)
@@ -324,3 +324,65 @@ trigger_sevent(struct script_event *ev, VA_DOTS)
     } \
 } while (0)
 
+/* Broker functions */
+
+/* Broker hash */
+struct broker *b_hash[255];
+
+#define DELETED ((struct broker*)1)
+#define BHASH(o) (((int)(o) >> sizeof(struct broker *)) & 255)
+struct broker **broker_from_obj(void *obj)
+{
+  struct broker **bucket = b_hash + BHASH(obj);
+  while (*bucket && (*bucket)->obj != obj)
+    {
+      bucket = &(*bucket)->b_next;
+    }
+  return bucket;
+}
+
+struct broker *
+get_obj_broker(void *obj)
+{
+  struct broker **bucket = broker_from_obj(obj);
+  if (!obj)
+    return NULL;
+
+  /* Not found, allocate a new one */
+  if (!*bucket)
+    {
+      struct broker *tmp = (struct broker *)malloc(sizeof(struct broker));
+      if (!tmp)
+       return NULL;
+
+      *bucket = tmp;
+      tmp->obj = obj;
+      tmp->ref = 0;
+      tmp->valid = 1;
+      tmp->b_next = NULL;
+    }
+  (*bucket)->ref++;
+
+  return *bucket;
+}
+
+void * get_broker_obj(struct broker *broker)
+{
+  if (broker->valid)
+    return broker->obj;
+
+  if (--broker->ref == 0)
+    {
+      struct broker **b = broker_from_obj(broker->obj);
+      Free(b);
+    }
+  return NULL;
+}
+
+void broker_inv_obj(void *obj)
+{
+  struct broker **b = broker_from_obj(obj);
+  if (*b)
+    (*b)->valid = 0;
+}
+
index ed1261d..dda07ac 100644 (file)
@@ -75,12 +75,32 @@ int trigger_sevent(struct script_event *ev, VA_DOTS);
 int register_listener(struct script_event *ev, struct listener *l);
 void unregister_listener(struct listener *l);
 
-struct gevents {
-    struct script_event cmdexecuted;
-    struct script_event detached;
-    struct script_event onattach;
-    struct script_event forechanged;
-    struct script_event processcaption;
+struct broker 
+{
+  void *obj;
+  int ref;
+  int valid;
+  struct broker *b_next;
+};
+
+/* At most one broker object is created and reused for one object.
+ * A counter is maintained for broker references. A broker to valid object can
+ * be dereferenced as many times as you wish. But once the object is
+ * invalidated, each dereference action will decrease the counter by one, and
+ * return a NULL pointer. The binding should further invalidate the script
+ * variable that refers to the broker. This scheme will work for languages
+ * that always treat host objects as reference and never do value copy.*/
+struct broker *get_obj_broker(void *obj);
+void * get_broker_obj(struct broker *broker);
+void broker_inv_obj(void *obj);
+
+struct gevents
+{
+  struct script_event cmdexecuted;
+  struct script_event detached;
+  struct script_event onattach;
+  struct script_event forechanged;
+  struct script_event processcaption;
 };
 extern struct gevents globalevents;
 #endif