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
|
@ -86,8 +86,15 @@ static hashtab_t *menu_hash;
|
||||||
static func_t menu_init;
|
static func_t menu_init;
|
||||||
static func_t menu_quit;
|
static func_t menu_quit;
|
||||||
static func_t menu_draw_hud;
|
static func_t menu_draw_hud;
|
||||||
|
static func_t menu_post;
|
||||||
static const char *top_menu;
|
static const char *top_menu;
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_menu_post (void)
|
||||||
|
{
|
||||||
|
PR_ExecuteProgram (&menu_pr_state, menu_post);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
menu_resolve_globals (progs_t *pr)
|
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")))
|
if (!(f = PR_FindFunction (pr, sym = "menu_draw_hud")))
|
||||||
goto error;
|
goto error;
|
||||||
menu_draw_hud = (func_t) (f - pr->pr_functions);
|
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")))
|
if (!(def = PR_FindGlobal (pr, sym = "time")))
|
||||||
goto error;
|
goto error;
|
||||||
menu_pr_state.globals.time = &G_FLOAT (pr, def->ofs);
|
menu_pr_state.globals.time = &G_FLOAT (pr, def->ofs);
|
||||||
|
@ -342,6 +352,7 @@ bi_Menu_SelectMenu (progs_t *pr)
|
||||||
game_target = IMT_CONSOLE;
|
game_target = IMT_CONSOLE;
|
||||||
if (menu->enter_hook) {
|
if (menu->enter_hook) {
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||||
|
run_menu_post ();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (name && *name)
|
if (name && *name)
|
||||||
|
@ -394,9 +405,13 @@ togglemenu_f (void)
|
||||||
static void
|
static void
|
||||||
quit_f (void)
|
quit_f (void)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (confirm_quit->int_val && menu_quit) {
|
if (confirm_quit->int_val && menu_quit) {
|
||||||
PR_ExecuteProgram (&menu_pr_state, 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;
|
return;
|
||||||
}
|
}
|
||||||
bi_Menu_Quit (&menu_pr_state);
|
bi_Menu_Quit (&menu_pr_state);
|
||||||
|
@ -503,6 +518,7 @@ Menu_Load (void)
|
||||||
RUA_Cbuf_SetCbuf (&menu_pr_state, con_data.cbuf);
|
RUA_Cbuf_SetCbuf (&menu_pr_state, con_data.cbuf);
|
||||||
InputLine_Progs_SetDraw (&menu_pr_state, C_DrawInputLine);
|
InputLine_Progs_SetDraw (&menu_pr_state, C_DrawInputLine);
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu_init);
|
PR_ExecuteProgram (&menu_pr_state, menu_init);
|
||||||
|
run_menu_post ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -524,11 +540,15 @@ Menu_Draw (view_t *view)
|
||||||
*menu_pr_state.globals.time = *con_data.realtime;
|
*menu_pr_state.globals.time = *con_data.realtime;
|
||||||
|
|
||||||
if (menu->draw) {
|
if (menu->draw) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
PR_RESET_PARAMS (&menu_pr_state);
|
PR_RESET_PARAMS (&menu_pr_state);
|
||||||
P_INT (&menu_pr_state, 0) = x;
|
P_INT (&menu_pr_state, 0) = x;
|
||||||
P_INT (&menu_pr_state, 1) = y;
|
P_INT (&menu_pr_state, 1) = y;
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu->draw);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,6 +578,7 @@ Menu_Draw (view_t *view)
|
||||||
P_INT (&menu_pr_state, 0) = x + item->x;
|
P_INT (&menu_pr_state, 0) = x + item->x;
|
||||||
P_INT (&menu_pr_state, 1) = y + item->y;
|
P_INT (&menu_pr_state, 1) = y + item->y;
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu->cursor);
|
PR_ExecuteProgram (&menu_pr_state, menu->cursor);
|
||||||
|
run_menu_post ();
|
||||||
} else {
|
} else {
|
||||||
Draw_Character (x + item->x, y + item->y,
|
Draw_Character (x + item->x, y + item->y,
|
||||||
12 + ((int) (*con_data.realtime * 4) & 1));
|
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;
|
*menu_pr_state.globals.time = *con_data.realtime;
|
||||||
|
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu_draw_hud);
|
PR_ExecuteProgram (&menu_pr_state, menu_draw_hud);
|
||||||
|
run_menu_post ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
||||||
{
|
{
|
||||||
menu_item_t *item;
|
menu_item_t *item;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!menu)
|
if (!menu)
|
||||||
return;
|
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, 1) = unicode;
|
||||||
P_INT (&menu_pr_state, 2) = down;
|
P_INT (&menu_pr_state, 2) = down;
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu->keyevent);
|
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;
|
return;
|
||||||
} else if (menu->items && menu->items[menu->cur_item]->func
|
} else if (menu->items && menu->items[menu->cur_item]->func
|
||||||
&& menu->items[menu->cur_item]->allkeys) {
|
&& 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;
|
P_INT (&menu_pr_state, 1) = key;
|
||||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||||
PR_PopFrame (&menu_pr_state);
|
PR_PopFrame (&menu_pr_state);
|
||||||
if (R_INT (&menu_pr_state))
|
ret = R_INT (&menu_pr_state);
|
||||||
|
run_menu_post ();
|
||||||
|
if (ret)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!menu || !menu->items)
|
if (!menu || !menu->items)
|
||||||
|
@ -625,10 +652,12 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
||||||
P_INT (&menu_pr_state, 1) = key;
|
P_INT (&menu_pr_state, 1) = key;
|
||||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||||
PR_PopFrame (&menu_pr_state);
|
PR_PopFrame (&menu_pr_state);
|
||||||
|
run_menu_post ();
|
||||||
} else {
|
} else {
|
||||||
menu = item;
|
menu = item;
|
||||||
if (menu->enter_hook) {
|
if (menu->enter_hook) {
|
||||||
PR_ExecuteProgram (&menu_pr_state, 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);
|
menu = Hash_Find (menu_hash, top_menu);
|
||||||
if (menu && menu->enter_hook) {
|
if (menu && menu->enter_hook) {
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||||
|
run_menu_post ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,6 +690,7 @@ Menu_Leave ()
|
||||||
if (menu) {
|
if (menu) {
|
||||||
if (menu->leave_hook) {
|
if (menu->leave_hook) {
|
||||||
PR_ExecuteProgram (&menu_pr_state, menu->leave_hook);
|
PR_ExecuteProgram (&menu_pr_state, menu->leave_hook);
|
||||||
|
run_menu_post ();
|
||||||
}
|
}
|
||||||
menu = menu->parent;
|
menu = menu->parent;
|
||||||
if (!menu) {
|
if (!menu) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "AutoreleasePool.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
@ -588,3 +589,8 @@ void () menu_init =
|
||||||
void () menu_draw_hud =
|
void () menu_draw_hud =
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void menu_post ()
|
||||||
|
{
|
||||||
|
[AutoreleasePool release];
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
|
||||||
|
@class Array;
|
||||||
|
|
||||||
@interface AutoreleasePool: Object
|
@interface AutoreleasePool: Object
|
||||||
{
|
{
|
||||||
unsigned count;
|
Array array;
|
||||||
id [] array;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void) addObject: (id)anObject;
|
+ (void) addObject: (id)anObject;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "AutoreleasePool.h"
|
#include "AutoreleasePool.h"
|
||||||
#include "Stack.h"
|
//#include "Stack.h"
|
||||||
|
|
||||||
@static AutoreleasePool sharedInstance;
|
@static AutoreleasePool sharedInstance;
|
||||||
@static Stack poolStack;
|
//@static Stack poolStack;
|
||||||
|
|
||||||
@interface AutoreleasePool (Private)
|
@interface AutoreleasePool (Private)
|
||||||
- (void) addItem: (id)anItem;
|
- (void) addItem: (id)anItem;
|
||||||
|
@ -15,19 +15,28 @@
|
||||||
if (!(self = [super init]))
|
if (!(self = [super init]))
|
||||||
return NIL;
|
return NIL;
|
||||||
|
|
||||||
if (!poolStack)
|
//if (!poolStack)
|
||||||
poolStack = [Stack new];
|
// poolStack = [Stack new];
|
||||||
|
|
||||||
if (!sharedInstance)
|
if (!sharedInstance)
|
||||||
sharedInstance = self;
|
sharedInstance = self;
|
||||||
|
|
||||||
|
array = [[Array alloc] init];
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void) addObject: (id)anObject
|
+ (void) addObject: (id)anObject
|
||||||
{
|
{
|
||||||
|
if (!sharedInstance)
|
||||||
|
[[AutoreleasePool alloc] init];
|
||||||
|
[sharedInstance addObject: anObject];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) addObject: (id)anObject
|
- (void) addObject: (id)anObject
|
||||||
{
|
{
|
||||||
|
[array addItem: anObject];
|
||||||
|
[anObject release]; // the array retains the item, and releases when
|
||||||
|
// dealloced
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) retain
|
- (id) retain
|
||||||
|
@ -35,33 +44,33 @@
|
||||||
[self error: "Don't send -retain to an autorelease pool."];
|
[self error: "Don't send -retain to an autorelease pool."];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void) release
|
||||||
|
{
|
||||||
|
[sharedInstance release];
|
||||||
|
sharedInstance = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
- (/*oneway*/ void) release
|
- (/*oneway*/ void) release
|
||||||
{
|
{
|
||||||
if (self == sharedInstance)
|
|
||||||
sharedInstance = NIL;
|
|
||||||
|
|
||||||
[self dealloc];
|
[self dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
local unsigned i;
|
//local id tmp;
|
||||||
local id tmp;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
[array release];
|
||||||
[array[(integer)i] release]; //FIXME no unsigned addressing
|
|
||||||
|
|
||||||
obj_free (array);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This may be wrong.
|
This may be wrong.
|
||||||
Releasing an autorelease pool should keep popping pools off the stack
|
Releasing an autorelease pool should keep popping pools off the stack
|
||||||
until it gets to itself.
|
until it gets to itself.
|
||||||
*/
|
*/
|
||||||
do {
|
//do {
|
||||||
tmp = [poolStack pop];
|
// tmp = [poolStack pop];
|
||||||
} while (tmp != self);
|
//} while (tmp != self);
|
||||||
|
|
||||||
|
sharedInstance = NIL;
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -66,16 +66,19 @@ BOOL (id object) object_is_meta_class = #0;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@static BOOL allocDebug;
|
||||||
|
@static Class autoreleaseClass;
|
||||||
|
@static SEL autoreleaseSelector;
|
||||||
|
@static IMP autoreleaseIMP;
|
||||||
|
|
||||||
@implementation Object
|
@implementation Object
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
#if 0
|
//allocDebug = localinfo ("AllocDebug");
|
||||||
allocDebug = localinfo ("AllocDebug");
|
|
||||||
autoreleaseClass = [AutoreleasePool class];
|
autoreleaseClass = [AutoreleasePool class];
|
||||||
autoreleaseSelector = @selector(addObject:);
|
autoreleaseSelector = @selector(addObject:);
|
||||||
autoreleaseIMP = [autoreleaseClass methodForSelector: autoreleaseSelector];
|
autoreleaseIMP = [autoreleaseClass methodForSelector: autoreleaseSelector];
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +296,7 @@ BOOL (id object) object_is_meta_class = #0;
|
||||||
|
|
||||||
- (id) autorelease
|
- (id) autorelease
|
||||||
{
|
{
|
||||||
|
autoreleaseIMP (autoreleaseClass, autoreleaseSelector, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) retainCount
|
- (unsigned) retainCount
|
||||||
|
|
|
@ -8,5 +8,7 @@ qwaq.dat
|
||||||
@top_srcdir@/ruamoko/lib/string.r
|
@top_srcdir@/ruamoko/lib/string.r
|
||||||
@top_srcdir@/ruamoko/lib/Object.r
|
@top_srcdir@/ruamoko/lib/Object.r
|
||||||
@top_srcdir@/ruamoko/lib/Protocol.r
|
@top_srcdir@/ruamoko/lib/Protocol.r
|
||||||
|
@top_srcdir@/ruamoko/lib/Array.r
|
||||||
|
@top_srcdir@/ruamoko/lib/AutoreleasePool.r
|
||||||
@srcdir@/test.r
|
@srcdir@/test.r
|
||||||
@srcdir@/main.qc
|
@srcdir@/main.qc
|
||||||
|
|
Loading…
Reference in New Issue