Added a generic interface for using handles in GIB and made GIB threads

use it.
This commit is contained in:
Brian Koropoff 2003-04-14 01:17:55 +00:00
parent e707e9bb89
commit 11e2f0d16a
8 changed files with 195 additions and 36 deletions

View file

@ -104,5 +104,11 @@ void GIB_Thread_Execute (void);
void GIB_Init (qboolean sandbox);
// Handle interface
unsigned long int GIB_Handle_New (void *data, unsigned short int class);
void GIB_Handle_Free (unsigned long int num, unsigned short int class);
void *GIB_Handle_Get (unsigned long int num, unsigned short int class);
unsigned short int GIB_Handle_Class_New (void);
#endif

44
include/gib_handle.h Normal file
View file

@ -0,0 +1,44 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2002 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __gib_handle_h
#define __gib_handle_h
typedef struct gib_handle_s {
unsigned short int class;
unsigned long int num;
void *data;
struct gib_handle_s *next;
} gib_handle_t;
void GIB_Handle_Init (void);
#endif

View file

@ -43,12 +43,13 @@ typedef struct gib_thread_s {
void GIB_Thread_Add (gib_thread_t *thread);
void GIB_Thread_Remove (gib_thread_t *thread);
void GIB_Thread_Delete (gib_thread_t *thread);
gib_thread_t *GIB_Thread_Find (unsigned long int id);
gib_thread_t *GIB_Thread_New (void);
void GIB_Thread_Init (void);
int GIB_Event_Register (const char *name, gib_function_t *func);
void GIB_Event_Init (void);
extern gib_thread_t *gib_threads;
extern gib_thread_t *gib_thread_first, *gib_thread_last;
extern unsigned short int gib_thread_class;
#endif

View file

@ -6,6 +6,6 @@ lib_LTLIBRARIES= libQFgib.la
libQFgib_la_LDFLAGS= -version-info 1:0:0
libQFgib_la_SOURCES= \
gib_buffer.c gib_builtin.c gib_execute.c gib_function.c gib_parse.c gib_process.c \
gib_regex.c gib_thread.c gib_vars.c gib_init.c gib_tree.c gib_semantics.c ops.c \
exp.c regex.c
gib_buffer.c gib_builtin.c gib_execute.c gib_function.c gib_parse.c gib_handle.c \
gib_process.c gib_regex.c gib_thread.c gib_vars.c gib_init.c gib_tree.c \
gib_semantics.c ops.c exp.c regex.c

View file

@ -63,6 +63,7 @@ const char rcsid[] =
#include "gib_vars.h"
#include "gib_regex.h"
#include "gib_thread.h"
#include "gib_handle.h"
#include "gib_builtin.h"
char gib_null_string[] = "";
@ -628,10 +629,9 @@ GIB_Thread_Kill_f (void)
cbuf_t *cur;
unsigned long int id = strtoul (GIB_Argv (1), 0, 10);
thread = GIB_Thread_Find (id);
thread = GIB_Handle_Get (id, gib_thread_class);
if (!thread) {
GIB_Error ("thread", "%s: thread %lu does not exist.", GIB_Argv (0),
id);
GIB_Error ("thread", "%s: thread %lu does not exist.", GIB_Argv (0), id);
return;
}
@ -655,7 +655,7 @@ GIB_Thread_List_f (void)
else if (GIB_CanReturn ()) {
gib_thread_t *cur;
for (cur = gib_threads; cur; cur = cur->next)
for (cur = gib_thread_first; cur; cur = cur->next)
dsprintf (GIB_Return (0), "%lu", cur->id);
}
}

103
libs/gib/gib_handle.c Normal file
View file

@ -0,0 +1,103 @@
/*
bi_gib.c
GIB <-> Ruamoko interface
Copyright (C) 2003 Brian Koropoff
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "QF/gib.h"
#include "gib_handle.h"
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static unsigned long int gib_next_handle, gib_next_class;
static gib_handle_t *gib_unused_handles;
static gib_handle_t **gib_handles;
static unsigned long int gib_handles_size;
unsigned long int
GIB_Handle_New (void *data, unsigned short int class)
{
gib_handle_t *new;
if (gib_unused_handles) {
new = gib_unused_handles;
gib_unused_handles = new->next;
} else {
unsigned long int num = gib_next_handle++;
if (num >= gib_handles_size) {
gib_handles_size += 256;
gib_handles = realloc (gib_handles, sizeof(void *) * gib_handles_size);
}
new = calloc (1, sizeof (gib_handle_t));
new->num = num;
}
new->data = data;
new->class = class;
gib_handles[new->num] = new;
return new->num;
}
void
GIB_Handle_Free (unsigned long int num, unsigned short int class)
{
gib_handle_t *hand;
if (num >= gib_next_handle || gib_handles[num]->class != class)
return;
hand = gib_handles[num];
gib_handles[num] = 0;
hand->next = gib_unused_handles;
gib_unused_handles = hand;
}
void *
GIB_Handle_Get (unsigned long int num, unsigned short int class)
{
if (num >= gib_next_handle || gib_handles[num]->class != class)
return 0;
return gib_handles[num]->data;
}
unsigned short int
GIB_Handle_Class_New (void)
{
return gib_next_class++;
}
void
GIB_Handle_Init (void)
{
gib_handles_size = 256;
gib_handles = calloc (gib_handles_size, sizeof (gib_handle_t *));
gib_next_class = 0;
gib_next_handle = 0;
gib_unused_handles = 0;
}

View file

@ -53,6 +53,7 @@ const char rcsid[] =
#include "gib_regex.h"
#include "gib_builtin.h"
#include "gib_thread.h"
#include "gib_handle.h"
static void
GIB_Exec_Override_f (void)
@ -100,6 +101,8 @@ GIB_Init (qboolean sandbox)
Cmd_RemoveCommand ("exec");
Cmd_AddCommand ("exec", GIB_Exec_Override_f, "Execute a script file.");
}
// Initialize handle system
GIB_Handle_Init ();
// Initialize variables
GIB_Var_Init ();
// Initialize regex cache
@ -108,4 +111,5 @@ GIB_Init (qboolean sandbox)
GIB_Builtin_Init (sandbox);
// Initialize event system
GIB_Event_Init ();
}

View file

@ -45,23 +45,31 @@ const char rcsid[] = "$Id$";
#include "QF/dstring.h"
#include "QF/hash.h"
#include "gib_handle.h"
#include "gib_tree.h"
#include "gib_function.h"
#include "gib_thread.h"
gib_thread_t *gib_threads = 0;
gib_thread_t **gib_thread_p = &gib_threads;
gib_thread_t *gib_thread_first = 0;
gib_thread_t *gib_thread_last = 0;
unsigned short int gib_thread_class;
hashtab_t *gib_events;
static unsigned long int nextid = 0;
void
GIB_Thread_Add (gib_thread_t * thread)
{
thread->prev = *gib_thread_p;
*gib_thread_p = thread;
gib_thread_p = &thread->next;
if (!gib_thread_first)
gib_thread_first = thread;
thread->prev = gib_thread_last;
if (!gib_thread_last)
gib_thread_last = thread;
else {
gib_thread_last->next = thread;
gib_thread_last = thread;
}
}
void
@ -70,24 +78,11 @@ GIB_Thread_Remove (gib_thread_t * thread)
if (thread->prev)
thread->prev->next = thread->next;
else
gib_threads = thread->next;
gib_thread_first = thread->next;
if (thread->next)
thread->next->prev = thread->prev;
else if (thread->prev)
gib_thread_p = &thread->prev->next;
else
gib_thread_p = &gib_threads;
}
gib_thread_t *
GIB_Thread_Find (unsigned long int id)
{
gib_thread_t *cur;
for (cur = gib_threads; cur; cur = cur->next)
if (cur->id == id)
return cur;
return 0;
gib_thread_last = thread->next;
}
gib_thread_t *
@ -96,8 +91,7 @@ GIB_Thread_New (void)
gib_thread_t *new = calloc (1, sizeof (gib_thread_t));
new->cbuf = Cbuf_New (GIB_Interpreter ());
new->id = nextid;
nextid++;
new->id = GIB_Handle_New (new, gib_thread_class);
return new;
}
@ -105,6 +99,7 @@ void
GIB_Thread_Delete (gib_thread_t * thread)
{
Cbuf_DeleteStack (thread->cbuf);
GIB_Handle_Free (thread->id, gib_thread_class);
free (thread);
}
@ -113,20 +108,26 @@ GIB_Thread_Execute (void)
{
gib_thread_t *cur, *tmp;
if (!gib_threads)
if (!gib_thread_first)
return;
for (cur = gib_threads; cur; cur = tmp) {
for (cur = gib_thread_first; cur; cur = tmp) {
tmp = cur->next;
if (GIB_DATA(cur->cbuf)->program)
Cbuf_Execute_Stack (cur->cbuf);
else {
GIB_Thread_Remove (cur);
GIB_Thread_Delete (cur);
}
}
}
}
void
GIB_Thread_Init (void)
{
gib_thread_class = GIB_Handle_Class_New ();
}
static const char *
GIB_Event_Get_Key (void *ele, void *ptr)
{