[qwaq] Rework allocation to use retain/release

It currently dies when single stepping or exiting due to EditBuffer's
retain count not getting incremented when initialized. This is because
EditBuffer is initialized in C and thus does not call Object's -init.
This commit is contained in:
Bill Currie 2020-03-30 16:30:58 +09:00
parent d7df2fa63d
commit 8a7fbdfc9f
27 changed files with 224 additions and 73 deletions

View file

@ -24,8 +24,9 @@
Window *locals_window;
LocalsView *locals_view;
}
-(qdb_target_t)target;
+(Debugger *)withTarget:(qdb_target_t)target;
-initWithTarget:(qdb_target_t) target;
-(qdb_target_t)target;
-handleDebugEvent;
@end

View file

@ -13,6 +13,11 @@
#include "qwaq-app.h"
@implementation Debugger
+(Debugger *)withTarget:(qdb_target_t)target
{
return [[[self alloc] initWithTarget:target] autorelease];
}
-(qdb_target_t)target
{
return target;
@ -26,12 +31,18 @@
self.target = target;
files = [[Array array] retain];
source_window = [[Window alloc] initWithRect: {nil, [application size]}];
source_window = [Window withRect: {nil, [application size]}];
[application addView:source_window];
return self;
}
-(void)dealloc
{
[files release];
[super dealloc];
}
-(Editor *) find_file:(string) filename
{
Editor *file;
@ -44,7 +55,7 @@
Rect rect = {{1, 1}, [source_window size]};
rect.extent.width -= 2;
rect.extent.height -= 2;
file = [[Editor alloc] initWithRect: rect file: filename];
file = [Editor withRect:rect file:filename];
[files addObject: file];
return file;
}
@ -54,7 +65,7 @@
qdb_state_t state = qdb_get_state (target);
current_file = [self find_file: state.file];
file_proxy = [[ProxyView alloc] initWithView: current_file];
file_proxy = [ProxyView withView: current_file];
[[current_file gotoLine:state.line - 1] highlightLine];
[[current_file onEvent] addListener: self :@selector(proxy_event::)];
//FIXME id<View>?
@ -62,11 +73,10 @@
[source_window setTitle: [current_file filename]];
[source_window redraw];
locals_window = [[Window alloc] initWithRect: {{0, 0}, {40, 10}}];
locals_window = [Window withRect:{{0, 0}, {40, 10}}];
[locals_window setBackground: color_palette[064]];
[locals_window setTitle: "Locals"];
locals_view = [[LocalsView alloc] initWithRect: {{1, 1}, {38, 8}}
target: target];
locals_view = [LocalsView withRect:{{1, 1}, {38, 8}} target:target];
[locals_window insertSelected: locals_view];
[application addView: locals_window];

View file

@ -15,8 +15,9 @@
qdb_def_t *defs;
void *data;
}
-initWithRect:(Rect)rect target:(qdb_target_t) target;
-setFunction:(unsigned) fnum;
+(LocalsView *)withRect:(Rect)rect target:(qdb_target_t)target;
-initWithRect:(Rect)rect target:(qdb_target_t)target;
-setFunction:(unsigned)fnum;
@end
#endif

View file

@ -5,6 +5,11 @@
@implementation LocalsView
+(LocalsView *)withRect:(Rect)rect target:(qdb_target_t)target
{
return [[[self alloc] initWithRect:rect target:target] autorelease];
}
-initWithRect:(Rect)rect target:(qdb_target_t) target
{
if (!(self = [super initWithRect:rect])) {
@ -22,6 +27,18 @@
return self;
}
-(void)dealloc
{
if (defs) {
obj_free (defs);
defs = nil;
}
if (data) {
obj_free (data);
data = nil;
}
}
-setFunction:(unsigned) fnum
{
if (current_fnum == fnum) {

View file

@ -26,6 +26,8 @@ typedef struct eb_color_s {
{
struct edit_buffer_s *buffer;
}
+(EditBuffer *)buffer;
+(EditBuffer *)withFile:(string)filename;
-init;
-initWithFile: (string) filename;
- (unsigned) nextChar: (unsigned) charPtr;

View file

@ -1,6 +1,16 @@
#include "editor/editbuffer.h"
@implementation EditBuffer
+(EditBuffer *)buffer
{
return [[[self alloc] init] autorelease];
}
+(EditBuffer *)withFile:(string)filename
{
return [[[self alloc] initWithFile:filename] autorelease];
}
- init = #0;
- initWithFile: (string) filename = #0;
- (void) dealloc = #0;

View file

@ -22,6 +22,7 @@
unsigned line_count;
string filename;
}
+(Editor *)withRect:(Rect)rect file:(string)filename;
-initWithRect:(Rect) rect file:(string) filename;
-(string)filename;
-scrollUp:(unsigned) count;

View file

@ -5,20 +5,32 @@
@implementation Editor
+(Editor *)withRect:(Rect)rect file:(string)filename
{
return [[[self alloc] initWithRect:rect file:filename] autorelease];
}
-initWithRect:(Rect) rect file:(string) filename
{
if (!(self = [super initWithRect: rect])) {
return nil;
}
self.filename = filename;
buffer = [[EditBuffer alloc] initWithFile: filename];
buffer = [[EditBuffer withFile:filename] retain];
line_count = [buffer countLines: {0, [buffer textSize]}];
linebuffer = [DrawBuffer buffer: { xlen, 1 }];
linebuffer = [[DrawBuffer buffer: { xlen, 1 }] retain];
growMode = gfGrowHi;
options = ofCanFocus | ofRelativeEvents;
return self;
}
-(void)dealloc
{
[buffer release];
[linebuffer release];
[super dealloc];
}
-(string)filename
{
return filename;

View file

@ -46,7 +46,7 @@ arp_end (void)
screen = [TextContext screen];
screenSize = [screen size];
objects = [[Group alloc] initWithContext: screen owner: nil];
objects = [[Group withContext: screen owner: nil] retain];
[screen bkgd: color_palette[047]];
[screen scrollok: 1];
@ -84,7 +84,7 @@ arp_end (void)
return debugger;
}
}
debugger = [[Debugger alloc] initWithTarget: target];
debugger = [Debugger withTarget: target];
[debuggers addObject: debugger];
return debugger;
}
@ -153,11 +153,14 @@ int main (int argc, string *argv)
fence = 0;
//while (!fence) {}
arp_start ();
application = [[QwaqApplication app] retain];
arp_end ();
[application run];
[application release];
qwaq_event_t event;
get_event (&event); // XXX need a "wait for queue idle"
return 0;
}

View file

@ -20,6 +20,9 @@
ListenerGroup *onAuto;
ListenerGroup *onHover;
}
+(Button *)withPos: (Point) pos releasedIcon: (DrawBuffer *) released
pressedIcon: (DrawBuffer *) pressed;
+(Button *)withRect: (Rect) rect; // invisible button
-initWithPos: (Point) pos releasedIcon: (DrawBuffer *) released
pressedIcon: (DrawBuffer *) pressed;
-initWithRect: (Rect) rect; // invisible button

View file

@ -2,6 +2,20 @@
#include "ui/listener.h"
@implementation Button
+(Button *)withPos:(Point)pos releasedIcon:(DrawBuffer *)released
pressedIcon:(DrawBuffer *)pressed
{
return [[[self alloc] initWithPos:pos
releasedIcon:released
pressedIcon:pressed] autorelease];
}
+(Button *)withRect:(Rect)rect
{
return [[[self alloc] initWithRect:rect] autorelease];
}
-initWithPos: (Point) pos releasedIcon: (DrawBuffer *) released
pressedIcon: (DrawBuffer *) pressed
{
@ -10,14 +24,14 @@
if (!(self = [super initWithRect: {pos, size}])) {
return nil;
}
icon[0] = released;
icon[1] = pressed;
onPress = [[ListenerGroup alloc] init];
onRelease = [[ListenerGroup alloc] init];
onClick = [[ListenerGroup alloc] init];
onDrag = [[ListenerGroup alloc] init];
onAuto = [[ListenerGroup alloc] init];
onHover = [[ListenerGroup alloc] init];
icon[0] = [released retain];
icon[1] = [pressed retain];
onPress = [ListenerGroup listener];
onRelease = [ListenerGroup listener];
onClick = [ListenerGroup listener];
onDrag = [ListenerGroup listener];
onAuto = [ListenerGroup listener];
onHover = [ListenerGroup listener];
return self;
}
@ -28,15 +42,22 @@
}
icon[0] = nil;
icon[1] = nil;
onPress = [[ListenerGroup alloc] init];
onRelease = [[ListenerGroup alloc] init];
onClick = [[ListenerGroup alloc] init];
onDrag = [[ListenerGroup alloc] init];
onAuto = [[ListenerGroup alloc] init];
onHover = [[ListenerGroup alloc] init];
onPress = [ListenerGroup listener];
onRelease = [ListenerGroup listener];
onClick = [ListenerGroup listener];
onDrag = [ListenerGroup listener];
onAuto = [ListenerGroup listener];
onHover = [ListenerGroup listener];
return self;
}
-(void)dealloc
{
[icon[0] release];
[icon[1] release];
[super dealloc];
}
-draw
{
[super draw];

View file

@ -39,8 +39,8 @@
Point cursor;
int background;
}
+ (DrawBuffer *) buffer: (Extent) size;
- initWithSize: (Extent) size;
+(DrawBuffer *)buffer:(Extent)size;
-initWithSize:(Extent)size;
@end
#endif//__qwaq_ui_draw_h

View file

@ -5,9 +5,9 @@
@implementation DrawBuffer
+ (DrawBuffer *) buffer: (Extent) size
+(DrawBuffer *)buffer:(Extent)size
{
return [[self alloc] initWithSize: size];
return [[[self alloc] initWithSize: size] autorelease];
}
- initWithSize: (Extent) size
@ -20,6 +20,12 @@
return self;
}
-(void)dealloc
{
obj_free (buffer);
[super dealloc];
}
- (Extent) size
{
return size;

View file

@ -17,7 +17,8 @@
int focused;
id<TextContext> context;
}
-initWithContext: (id<TextContext>) context owner: (View *) owner;
+(Group *)withContext:(id<TextContext>)context owner:(View *)owner;
-initWithContext:(id<TextContext>)context owner:(View *)owner;
-(id<TextContext>)context;
-setContext: (id<TextContext>) context;
-insert: (View *) view;

View file

@ -7,6 +7,11 @@
@implementation Group
+(Group *)withContext:(id<TextContext>)context owner:(View *)owner
{
return [[[self alloc] initWithContext:context owner:owner] autorelease];
}
-initWithContext: (id<TextContext>) context owner: (View *) owner
{
if (!(self = [super init])) {
@ -22,6 +27,7 @@
-(void)dealloc
{
[views release];
[super dealloc];
}
-(id<TextContext>)context
@ -85,6 +91,7 @@ makeFirst (Group *self, int viewIndex)
{
View *view = [self.views objectAtIndex: viewIndex];
// add before remove to avoid freeing view
[self.views addObject: view];
[self.views removeObjectAtIndex: viewIndex];
[view raise];

View file

@ -11,6 +11,7 @@
SEL message;
IMP imp;
}
+(Listener *)listenerWithResponder:(id)responder :(SEL)message;
-initWithResponder: (id) responder :(SEL)message;
-(void) respond: (void *) caller_data;
-(void) respond: (void *) caller_data withObject:(void *)anObject;
@ -21,6 +22,7 @@
{
Array *listeners;
}
+(ListenerGroup *)listener;
-init;
-addListener: (id) responder :(SEL)message;
-removeListener: (id) responder :(SEL)message;

View file

@ -5,6 +5,11 @@
@class Array;
@implementation Listener
+(Listener *)listenerWithResponder:(id)responder :(SEL)message
{
return [[[self alloc] initWithResponder:responder :message] autorelease];
}
-initWithResponder: (id) responder :(SEL)message
{
if (!(self = [super init])) {
@ -33,6 +38,11 @@
@end
@implementation ListenerGroup : Object
+(ListenerGroup *)listener
{
return [[[self alloc] init] autorelease];
}
-init
{
if (!(self = [super init])) {
@ -44,10 +54,9 @@
-addListener: (id) responder :(SEL)message
{
Listener *listener = [[Listener alloc] initWithResponder: responder
: message];
Listener *listener = [Listener listenerWithResponder:responder :message];
if (listener) {
[listeners addObject: listener];
[listeners addObject:listener];
}
return self;
}

View file

@ -10,8 +10,9 @@
View *view;
Group *owner;
}
-initWithView:(View *) view;
-setView: (View *) view;
+(ProxyView *)withView:(View *)view;
-initWithView:(View *)view;
-setView:(View *)view;
@end
@interface ProxyView (View) <View, TextContext>

View file

@ -2,6 +2,11 @@
#include "ui/proxyview.h"
@implementation ProxyView
+(ProxyView *)withView:(View *)view
{
return [[[self alloc] initWithView:view] autorelease];
}
- (void) forward: (SEL) sel : (@va_list) args
{
if (!view) {
@ -15,7 +20,7 @@
if (!(self = [super init])) {
return nil;
}
self.view = view;
self.view = [view retain];
return self;
}
@ -35,7 +40,10 @@
[self.view hide];
[self.view setContext:nil];
[view retain];
[self.view release];
self.view = view;
[view setContext:[owner context]];
if (state & sfDrawn) {
[view draw];

View file

@ -36,6 +36,10 @@
+ (void) doupdate;
+ (TextContext *) screen;
+(TextContext *)textContext;
+(TextContext *)withRect:(Rect)rect;
+(TextContext *)withWindow:(window_t)window;
-init;
-initWithRect: (Rect) rect;
-initWithWindow: (window_t) window;

View file

@ -22,11 +22,26 @@ static TextContext *screen;
+ (TextContext *) screen
{
if (!screen) {
screen = [[TextContext alloc] init];
screen = [[TextContext textContext] retain];
}
return screen;
}
+(TextContext *)textContext
{
return [[[self alloc] init] autorelease];
}
+(TextContext *)withRect:(Rect)rect
{
return [[[self alloc] initWithRect:rect] autorelease];
}
+(TextContext *)withWindow:(window_t)window
{
return [[[self alloc] initWithWindow:window] autorelease];
}
- init
{
if (!(self = [super init])) {

View file

@ -9,8 +9,9 @@
int length;
}
// title always centered at top of owner
-initWithTitle:(string) title;
-setTitle:(string) newTitle;
+(TitleBar *)withTitle:(string)title;
-initWithTitle:(string)title;
-setTitle:(string)newTitle;
@end
#endif//__qwaq_ui_titlebar_h

View file

@ -5,6 +5,11 @@
@implementation TitleBar
+(TitleBar *)withTitle:(string)title
{
return [[[self alloc] initWithTitle:title] autorelease];
}
-initWithTitle:(string) title
{
if (!(self = [super init])) {

View file

@ -113,8 +113,11 @@ enum {
ListenerGroup *onReleaseFocus;
ListenerGroup *onEvent;
}
-initWithRect: (Rect) rect;
-initWithRect: (Rect) rect options:(int)options;
+(View *)viewWithRect:(Rect)rect;
+(View *)viewWithRect:(Rect)rect options:(int)options;
-initWithRect:(Rect)rect;
-initWithRect:(Rect)rect options:(int)options;
@end
@interface View (TextContext) <TextContext>

View file

@ -5,14 +5,29 @@
@implementation View
+(View *)viewWithRect:(Rect)rect
{
return [[[self alloc] initWithRect:rect] autorelease];
}
+(View *)viewWithRect:(Rect)rect options:(int)options
{
return [[[self alloc] initWithRect:rect options:options] autorelease];
}
static void view_init(View *self)
{
self.onReceiveFocus = [ListenerGroup listener];
self.onReleaseFocus = [ListenerGroup listener];
self.onEvent = [ListenerGroup listener];
}
-init
{
if (!(self = [super init])) {
return nil;
}
onReceiveFocus = [[ListenerGroup alloc] init];
onReleaseFocus = [[ListenerGroup alloc] init];
onEvent = [[ListenerGroup alloc] init];
view_init (self);
return self;
}
@ -21,11 +36,10 @@
if (!(self = [super init])) {
return nil;
}
view_init (self);
self.rect = rect;
self.absRect = rect;
onReceiveFocus = [[ListenerGroup alloc] init];
onReleaseFocus = [[ListenerGroup alloc] init];
onEvent = [[ListenerGroup alloc] init];
return self;
}
@ -34,12 +48,11 @@
if (!(self = [super init])) {
return nil;
}
view_init (self);
self.rect = rect;
self.absRect = rect;
self.options = options;
onReceiveFocus = [[ListenerGroup alloc] init];
onReleaseFocus = [[ListenerGroup alloc] init];
onEvent = [[ListenerGroup alloc] init];
return self;
}
@ -48,6 +61,9 @@
if (owner) {
[owner remove:self];
}
[onReceiveFocus release];
[onReleaseFocus release];
[onEvent release];
[super dealloc];
}

View file

@ -28,7 +28,7 @@
Button *bottomDrag;
TitleBar *titleBar;
}
+windowWithRect: (Rect) rect;
+(Window *)withRect: (Rect) rect;
-setTitle:(string) title;
-setBackground: (int) ch;
-insert: (View *) view;

View file

@ -12,7 +12,7 @@
@implementation Window
+windowWithRect: (Rect) rect
+(Window *)withRect: (Rect) rect
{
return [[[self alloc] initWithRect: rect] autorelease];
}
@ -28,29 +28,21 @@
return nil;
}
self.rect = rect;
textContext = [[TextContext alloc] initWithRect: rect];
textContext = [[TextContext withRect: rect] retain];
panel = create_panel ([(id)textContext window]);
objects = [[Group alloc] initWithContext: textContext owner: self];
objects = [[Group withContext:textContext owner:self] retain];
[self insert: titleBar = [[TitleBar alloc] initWithTitle:""]];
[self insert:titleBar = [TitleBar withTitle:""]];
topDrag = [[Button alloc] initWithRect: {{2, 0},
{xlen - 4, 1}}];
topLeftDrag = [[Button alloc] initWithRect: {{0, 0},
{2, 2}}];
topRightDrag = [[Button alloc] initWithRect: {{xlen - 2, 0},
{2, 2}}];
leftDrag = [[Button alloc] initWithRect: {{0, 2},
{1, ylen - 4}}];
rightDrag = [[Button alloc] initWithRect: {{xlen - 1, 2},
{1, ylen - 4}}];
bottomLeftDrag = [[Button alloc] initWithRect: {{0, ylen - 2},
{2, 2}}];
bottomRightDrag = [[Button alloc] initWithRect: {{xlen - 2, ylen - 2},
{2, 2}}];
bottomDrag = [[Button alloc] initWithRect: {{2, ylen - 1},
{xlen - 4, 1}}];
topDrag = [Button withRect:{{2, 0}, {xlen - 4, 1}}];
topLeftDrag = [Button withRect:{{0, 0}, {2, 2}}];
topRightDrag = [Button withRect:{{xlen - 2, 0}, {2, 2}}];
leftDrag = [Button withRect:{{0, 2}, {1, ylen - 4}}];
rightDrag = [Button withRect:{{xlen - 1, 2}, {1, ylen - 4}}];
bottomLeftDrag = [Button withRect:{{0, ylen - 2} , {2, 2}}];
bottomRightDrag = [Button withRect:{{xlen - 2, ylen - 2}, {2, 2}}];
bottomDrag = [Button withRect:{{2, ylen - 1}, {xlen - 4, 1}}];
[self insert: [topDrag setGrowMode: gfGrowHiX]];
[self insert: [topLeftDrag setGrowMode: gfGrowNone]];
[self insert: [topRightDrag setGrowMode: gfGrowX]];