// // History.m // RemoteR // // Created by Simon Urbanek on 2/14/11. // Copyright 2011 Simon Urbanek. All rights reserved. // #import "History.h" /** implements a history with one dirty entry (i.e. an entry which is still being edited but not committed yet) */ @implementation History - (id) init { self = [super init]; if (self != nil) { hist = [[NSMutableArray alloc] initWithCapacity: 128]; dirtyEntry = nil; pos = 0; } return self; } - (void) setHist: (NSArray *) entries { if (hist) [self resetAll]; [hist addObjectsFromArray: entries]; pos = [hist count]; } - (void) dealloc { [self resetAll]; [hist release]; [super dealloc]; } - (void) commit: (NSString*) entry { if (dirtyEntry != nil) [dirtyEntry release]; dirtyEntry = nil; [hist addObject:entry]; pos = [hist count]; } /** moves to the next entry; if out of the history, returns the dirty entry */ - (NSString*) next { NSInteger ac = [hist count]; if (pos < ac && ++pos < ac) return (NSString*) [hist objectAtIndex: pos]; // we're past the history, always return the dirty entry return dirtyEntry; } /** moves to the previous entry; if past the beginning, returns nil */ - (NSString*) prev { if (pos > 0) { pos--; return (NSString*) [hist objectAtIndex: pos]; } return nil; } /** returns the current entry (can be the dirty entry, too) */ - (NSString*) current { NSInteger ac = [hist count]; if (pos < ac) return (NSString*) [hist objectAtIndex: pos]; return dirtyEntry; } /** returns YES if the current position is in the dirty entry */ - (BOOL) isDirty { return (pos == [hist count]) ? YES : NO; } /** updates the dirty entry with the arg, if we're currently in the dirty position */ - (void) updateDirty: (NSString*) entry { if (pos == [hist count]) { if (entry == dirtyEntry) return; if (dirtyEntry != nil) [dirtyEntry release]; dirtyEntry = entry ? [entry retain] : nil; } } /** resets the entire history, position and ditry entry */ - (void) resetAll { [hist removeAllObjects]; if (dirtyEntry != nil) [dirtyEntry release]; pos = 0; } /** removes selected entry entry */ - (void) deleteEntry:(unsigned)index { [hist removeObjectAtIndex: index]; if (dirtyEntry != nil) [dirtyEntry release]; dirtyEntry = nil; pos = [hist count]; } /** returns a snapshot of the current histroy (w/o the dirty entry). */ - (NSArray*) entries { return [NSArray arrayWithArray: hist]; } /** encode dirty, position and history */ - (void) encodeWithCoder:(NSCoder *)coder{ [coder encodeObject:dirtyEntry]; [coder encodeObject:[NSNumber numberWithInt:pos]]; [coder encodeObject:hist]; } /** decoder init */ - (id) initWithCoder:(NSCoder *)coder{ if ((self = [self init])) { dirtyEntry = [coder decodeObject]; if (dirtyEntry) [dirtyEntry retain]; pos = [[coder decodeObject] intValue]; hist = [[NSMutableArray alloc] initWithCoder:coder]; } return self; } @end