mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-23 10:50:58 +00:00
First stab at implementing autorelease.
It's probably nowhere near right, but probably ok for now (I need to study the GNUStep code). I'm unhappy with the menu code hook, but it will have to do for now.
This commit is contained in:
parent
7acf8c0570
commit
4518e6af91
6 changed files with 78 additions and 26 deletions
|
@ -86,8 +86,15 @@ static hashtab_t *menu_hash;
|
|||
static func_t menu_init;
|
||||
static func_t menu_quit;
|
||||
static func_t menu_draw_hud;
|
||||
static func_t menu_post;
|
||||
static const char *top_menu;
|
||||
|
||||
static void
|
||||
run_menu_post (void)
|
||||
{
|
||||
PR_ExecuteProgram (&menu_pr_state, menu_post);
|
||||
}
|
||||
|
||||
static int
|
||||
menu_resolve_globals (progs_t *pr)
|
||||
{
|
||||
|
@ -101,6 +108,9 @@ menu_resolve_globals (progs_t *pr)
|
|||
if (!(f = PR_FindFunction (pr, sym = "menu_draw_hud")))
|
||||
goto error;
|
||||
menu_draw_hud = (func_t) (f - pr->pr_functions);
|
||||
if (!(f = PR_FindFunction (pr, sym = "menu_post")))
|
||||
goto error;
|
||||
menu_post = (func_t) (f - pr->pr_functions);
|
||||
if (!(def = PR_FindGlobal (pr, sym = "time")))
|
||||
goto error;
|
||||
menu_pr_state.globals.time = &G_FLOAT (pr, def->ofs);
|
||||
|
@ -342,6 +352,7 @@ bi_Menu_SelectMenu (progs_t *pr)
|
|||
game_target = IMT_CONSOLE;
|
||||
if (menu->enter_hook) {
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||
run_menu_post ();
|
||||
}
|
||||
} else {
|
||||
if (name && *name)
|
||||
|
@ -394,9 +405,13 @@ togglemenu_f (void)
|
|||
static void
|
||||
quit_f (void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (confirm_quit->int_val && menu_quit) {
|
||||
PR_ExecuteProgram (&menu_pr_state, menu_quit);
|
||||
if (!R_INT (&menu_pr_state))
|
||||
ret = R_INT (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
if (!ret)
|
||||
return;
|
||||
}
|
||||
bi_Menu_Quit (&menu_pr_state);
|
||||
|
@ -503,6 +518,7 @@ Menu_Load (void)
|
|||
RUA_Cbuf_SetCbuf (&menu_pr_state, con_data.cbuf);
|
||||
InputLine_Progs_SetDraw (&menu_pr_state, C_DrawInputLine);
|
||||
PR_ExecuteProgram (&menu_pr_state, menu_init);
|
||||
run_menu_post ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -524,11 +540,15 @@ Menu_Draw (view_t *view)
|
|||
*menu_pr_state.globals.time = *con_data.realtime;
|
||||
|
||||
if (menu->draw) {
|
||||
int ret;
|
||||
|
||||
PR_RESET_PARAMS (&menu_pr_state);
|
||||
P_INT (&menu_pr_state, 0) = x;
|
||||
P_INT (&menu_pr_state, 1) = y;
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->draw);
|
||||
if (R_INT (&menu_pr_state))
|
||||
ret = R_INT (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
if (!ret)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -558,6 +578,7 @@ Menu_Draw (view_t *view)
|
|||
P_INT (&menu_pr_state, 0) = x + item->x;
|
||||
P_INT (&menu_pr_state, 1) = y + item->y;
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->cursor);
|
||||
run_menu_post ();
|
||||
} else {
|
||||
Draw_Character (x + item->x, y + item->y,
|
||||
12 + ((int) (*con_data.realtime * 4) & 1));
|
||||
|
@ -570,12 +591,14 @@ Menu_Draw_Hud (view_t *view)
|
|||
*menu_pr_state.globals.time = *con_data.realtime;
|
||||
|
||||
PR_ExecuteProgram (&menu_pr_state, menu_draw_hud);
|
||||
run_menu_post ();
|
||||
}
|
||||
|
||||
void
|
||||
Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
||||
{
|
||||
menu_item_t *item;
|
||||
int ret;
|
||||
|
||||
if (!menu)
|
||||
return;
|
||||
|
@ -585,7 +608,9 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
|||
P_INT (&menu_pr_state, 1) = unicode;
|
||||
P_INT (&menu_pr_state, 2) = down;
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->keyevent);
|
||||
if (R_INT (&menu_pr_state))
|
||||
ret = R_INT (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
if (ret)
|
||||
return;
|
||||
} else if (menu->items && menu->items[menu->cur_item]->func
|
||||
&& menu->items[menu->cur_item]->allkeys) {
|
||||
|
@ -597,7 +622,9 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
|||
P_INT (&menu_pr_state, 1) = key;
|
||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||
PR_PopFrame (&menu_pr_state);
|
||||
if (R_INT (&menu_pr_state))
|
||||
ret = R_INT (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
if (!menu || !menu->items)
|
||||
|
@ -625,10 +652,12 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
|||
P_INT (&menu_pr_state, 1) = key;
|
||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||
PR_PopFrame (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
} else {
|
||||
menu = item;
|
||||
if (menu->enter_hook) {
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||
run_menu_post ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -651,6 +680,7 @@ Menu_Enter ()
|
|||
menu = Hash_Find (menu_hash, top_menu);
|
||||
if (menu && menu->enter_hook) {
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||
run_menu_post ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -660,6 +690,7 @@ Menu_Leave ()
|
|||
if (menu) {
|
||||
if (menu->leave_hook) {
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->leave_hook);
|
||||
run_menu_post ();
|
||||
}
|
||||
menu = menu->parent;
|
||||
if (!menu) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "AutoreleasePool.h"
|
||||
#include "menu.h"
|
||||
#include "file.h"
|
||||
#include "cmd.h"
|
||||
|
@ -588,3 +589,8 @@ void () menu_init =
|
|||
void () menu_draw_hud =
|
||||
{
|
||||
};
|
||||
|
||||
void menu_post ()
|
||||
{
|
||||
[AutoreleasePool release];
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
|
||||
#include "Object.h"
|
||||
|
||||
@class Array;
|
||||
|
||||
@interface AutoreleasePool: Object
|
||||
{
|
||||
unsigned count;
|
||||
id [] array;
|
||||
Array array;
|
||||
}
|
||||
|
||||
+ (void) addObject: (id)anObject;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "AutoreleasePool.h"
|
||||
#include "Stack.h"
|
||||
//#include "Stack.h"
|
||||
|
||||
@static AutoreleasePool sharedInstance;
|
||||
@static Stack poolStack;
|
||||
//@static Stack poolStack;
|
||||
|
||||
@interface AutoreleasePool (Private)
|
||||
- (void) addItem: (id)anItem;
|
||||
|
@ -15,19 +15,28 @@
|
|||
if (!(self = [super init]))
|
||||
return NIL;
|
||||
|
||||
if (!poolStack)
|
||||
poolStack = [Stack new];
|
||||
//if (!poolStack)
|
||||
// poolStack = [Stack new];
|
||||
|
||||
if (!sharedInstance)
|
||||
sharedInstance = self;
|
||||
|
||||
array = [[Array alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void) addObject: (id)anObject
|
||||
{
|
||||
if (!sharedInstance)
|
||||
[[AutoreleasePool alloc] init];
|
||||
[sharedInstance addObject: anObject];
|
||||
}
|
||||
|
||||
- (void) addObject: (id)anObject
|
||||
{
|
||||
[array addItem: anObject];
|
||||
[anObject release]; // the array retains the item, and releases when
|
||||
// dealloced
|
||||
}
|
||||
|
||||
- (id) retain
|
||||
|
@ -35,33 +44,33 @@
|
|||
[self error: "Don't send -retain to an autorelease pool."];
|
||||
}
|
||||
|
||||
+ (void) release
|
||||
{
|
||||
[sharedInstance release];
|
||||
sharedInstance = NIL;
|
||||
}
|
||||
|
||||
- (/*oneway*/ void) release
|
||||
{
|
||||
if (self == sharedInstance)
|
||||
sharedInstance = NIL;
|
||||
|
||||
[self dealloc];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
local unsigned i;
|
||||
local id tmp;
|
||||
//local id tmp;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
[array[(integer)i] release]; //FIXME no unsigned addressing
|
||||
|
||||
obj_free (array);
|
||||
[array release];
|
||||
|
||||
/*
|
||||
This may be wrong.
|
||||
Releasing an autorelease pool should keep popping pools off the stack
|
||||
until it gets to itself.
|
||||
*/
|
||||
do {
|
||||
tmp = [poolStack pop];
|
||||
} while (tmp != self);
|
||||
//do {
|
||||
// tmp = [poolStack pop];
|
||||
//} while (tmp != self);
|
||||
|
||||
sharedInstance = NIL;
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -66,16 +66,19 @@ BOOL (id object) object_is_meta_class = #0;
|
|||
|
||||
@end
|
||||
|
||||
@static BOOL allocDebug;
|
||||
@static Class autoreleaseClass;
|
||||
@static SEL autoreleaseSelector;
|
||||
@static IMP autoreleaseIMP;
|
||||
|
||||
@implementation Object
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
#if 0
|
||||
allocDebug = localinfo ("AllocDebug");
|
||||
//allocDebug = localinfo ("AllocDebug");
|
||||
autoreleaseClass = [AutoreleasePool class];
|
||||
autoreleaseSelector = @selector(addObject:);
|
||||
autoreleaseIMP = [autoreleaseClass methodForSelector: autoreleaseSelector];
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -293,7 +296,7 @@ BOOL (id object) object_is_meta_class = #0;
|
|||
|
||||
- (id) autorelease
|
||||
{
|
||||
|
||||
autoreleaseIMP (autoreleaseClass, autoreleaseSelector, self);
|
||||
}
|
||||
|
||||
- (unsigned) retainCount
|
||||
|
|
|
@ -8,5 +8,7 @@ qwaq.dat
|
|||
@top_srcdir@/ruamoko/lib/string.r
|
||||
@top_srcdir@/ruamoko/lib/Object.r
|
||||
@top_srcdir@/ruamoko/lib/Protocol.r
|
||||
@top_srcdir@/ruamoko/lib/Array.r
|
||||
@top_srcdir@/ruamoko/lib/AutoreleasePool.r
|
||||
@srcdir@/test.r
|
||||
@srcdir@/main.qc
|
||||
|
|
Loading…
Reference in a new issue