Archived
1

Added Change Notifications to MPExpression, MPMutableExpression and MPFunction

Removed -beginEditing and -endEditing
Optimized -fixSymbols
Updated Project File
This commit is contained in:
Kim Wittenburg
2014-05-18 01:06:49 +02:00
parent fa499d299c
commit 982b70d7fb
5 changed files with 119 additions and 65 deletions

View File

@@ -9,9 +9,10 @@
#import "MPExpression.h"
#import "MPFunction.h"
#import "MPException.h"
#import "MPRangePath.h"
#import "NSObject+MPStringTest.h"
#import "NSIndexPath+MPRemoveFirstIndex.h"
#import "NSIndexPath+MPReverseIndexPath.h"
NSString *MPAdditionOperator = @"+";
NSString *MPSubtractionOperator = @"-";
@@ -22,7 +23,6 @@ NSString *MPDivisionOperator = @"/";
- (NSInteger)lengthOfSymbol:(id)symbol;
- (void)validateSymbols:(NSArray *)symbols;
- (NSArray *)fixedSymbols:(NSArray *)symbols;
- (void)getSplitOffset:(out NSUInteger *)offset
inSymbolAtIndex:(out NSUInteger *)symbolIndex
forSplitLocation:(NSUInteger)loc;
@@ -53,7 +53,25 @@ NSString *MPDivisionOperator = @"/";
- (void)fixSymbols
{
_symbols = [self fixedSymbols:_symbols];
NSMutableArray *mutableSymbols = [_symbols mutableCopy];
for (NSInteger index = 0; index < mutableSymbols.count; index++) {
id next = index+1 < mutableSymbols.count ? mutableSymbols[index+1] : nil;
id current = mutableSymbols[index];
if ([current isString]) {
if ([current length] == 0) {
[mutableSymbols removeObjectAtIndex:index];
index--;
} else if ([next isString]) {
NSString *new = [NSString stringWithFormat:@"%@%@", current, next];
[mutableSymbols replaceObjectAtIndex:index withObject:new];
[mutableSymbols removeObjectAtIndex:index+1];
index--;
}
} else {
[(MPFunction *)current setParent:self];
}
}
_symbols = [mutableSymbols copy];
}
#pragma mark Primitive Methods
@@ -127,29 +145,6 @@ NSString *MPDivisionOperator = @"/";
}
}
- (NSArray *)fixedSymbols:(NSArray *)symbols
{
NSMutableArray *mutableSymbols = [symbols mutableCopy];
for (NSInteger index = 0; index < mutableSymbols.count; index++) {
id next = index+1 < mutableSymbols.count ? mutableSymbols[index+1] : nil;
id current = mutableSymbols[index];
if ([current isString]) {
if ([current length] == 0) {
[mutableSymbols removeObjectAtIndex:index];
index--;
} else if ([next isString]) {
NSString *new = [NSString stringWithFormat:@"%@%@", current, next];
[mutableSymbols replaceObjectAtIndex:index withObject:new];
[mutableSymbols removeObjectAtIndex:index+1];
index--;
}
} else {
[(MPFunction *)current setParent:self];
}
}
return [mutableSymbols copy];
}
- (void)getSplitOffset:(out NSUInteger *)offset
inSymbolAtIndex:(out NSUInteger *)symbolIndex
forSplitLocation:(NSUInteger)loc
@@ -420,9 +415,24 @@ NSString *MPDivisionOperator = @"/";
@end
@implementation MPExpression (MPChangeNotificationExtension)
- (void)symbolsChangedInRangePath:(MPRangePath *)rangePath replacementLength:(NSUInteger)length
{
if (!self.parent) {
return;
}
NSUInteger selfIndex = [self.parent indexOfChild:self];
NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:selfIndex];
MPRangePath *newPath = [[MPRangePath alloc] initWithLocation:newLocation length:rangePath.length];
[self.parent symbolsChangedInRangePath:newPath replacementLength:length];
}
@end
@implementation MPMutableExpression {
@protected
NSInteger _editCount;
NSRange editedRange;
NSRange replacementRange;
}
- (instancetype)initWithSymbols:(NSArray *)symbols
@@ -430,6 +440,8 @@ NSString *MPDivisionOperator = @"/";
[self validateSymbols:symbols];
self = [super initWithSymbols:nil];
if (self) {
editedRange = NSMakeRange(0, 0);
replacementRange = NSMakeRange(0, 0);
_symbols = [[NSMutableArray alloc] initWithArray:symbols
copyItems:YES];
[self fixSymbols];
@@ -439,7 +451,38 @@ NSString *MPDivisionOperator = @"/";
- (void)fixSymbols
{
_symbols = [[self fixedSymbols:_symbols] mutableCopy];
NSMutableArray *mutableSymbols = (NSMutableArray *)_symbols;
for (NSInteger index = 0; index < mutableSymbols.count; index++) {
id next = index+1 < mutableSymbols.count ? mutableSymbols[index+1] : nil;
id current = mutableSymbols[index];
if ([current isString]) {
if ([current length] == 0) {
[mutableSymbols removeObjectAtIndex:index];
if (index < replacementRange.location) {
replacementRange.location--;
} else if (index < NSMaxRange(replacementRange)-1) {
replacementRange.length--;
} else if (index == NSMaxRange(replacementRange)) {
editedRange.length++;
}
index--;
} else if ([next isString]) {
NSString *new = [NSString stringWithFormat:@"%@%@", current, next];
[mutableSymbols replaceObjectAtIndex:index withObject:new];
[mutableSymbols removeObjectAtIndex:index+1];
if (index < replacementRange.location) {
replacementRange.location--;
} else if (index < NSMaxRange(replacementRange)-1) {
replacementRange.length--;
} else if (index == NSMaxRange(replacementRange)-1) {
editedRange.length++;
}
index--;
}
} else {
[(MPFunction *)current setParent:self];
}
}
}
- (NSArray *)symbols
@@ -460,22 +503,27 @@ NSString *MPDivisionOperator = @"/";
// Locate the position, split the symbols
NSUInteger startIndex;
BOOL didSplitStart = NO;
if ([self numberOfSymbols] == 0) {
startIndex = 0;
} else {
[self splitSymbolsAtLocation:range.location
insertionIndex:&startIndex];
insertionIndex:&startIndex
didSplit:&didSplitStart];
}
// Perform the deletion
NSUInteger endIndex;
BOOL didSplitEnd = NO;
[self splitSymbolsAtLocation:NSMaxRange(range)
insertionIndex:&endIndex
didSplit:&didSplitEnd];
if (range.length > 0) {
NSUInteger endIndex;
[self splitSymbolsAtLocation:NSMaxRange(range)
insertionIndex:&endIndex];
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init];
for (NSUInteger index = startIndex; index < endIndex; index++) {
[indexes addIndex:index];
}
// TODO: Replace with removeObjectsInRange:
[(NSMutableArray *)_symbols removeObjectsAtIndexes:indexes];
}
@@ -486,15 +534,20 @@ NSString *MPDivisionOperator = @"/";
withObjectsFromArray:newSymbols];
}
// Revalidate structure and invalidate length
if (_editCount == 0) {
[self fixSymbols];
}
// Invalidate length and revalidate structure
_length = 0;
NSUInteger editingStart = startIndex - (didSplitStart?1:0);
NSUInteger editingLength = endIndex - startIndex + (didSplitStart?1:0) + (didSplitEnd?1:0);
editedRange = NSMakeRange(editingStart, editingLength);
replacementRange = NSMakeRange(startIndex, symbols.count);
[self fixSymbols];
MPRangePath *changePath = [[MPRangePath alloc] initWithRange:editedRange];
[self symbolsChangedInRangePath:changePath replacementLength:replacementRange.length];
}
- (void)splitSymbolsAtLocation:(NSUInteger)loc
insertionIndex:(out NSUInteger *)insertionIndex
didSplit:(out BOOL *)flag;
{
NSUInteger splitSymbolIndex;
NSUInteger splitOffset;
@@ -516,25 +569,10 @@ NSString *MPDivisionOperator = @"/";
[(NSMutableArray *)_symbols insertObject:rightPart
atIndex:splitSymbolIndex];
}
*flag = splitOffset != 0;
*insertionIndex = splitSymbolIndex;
}
- (void)beginEditing
{
_editCount++;
}
- (void)endEditing
{
if (_editCount == 0) {
return;
}
_editCount--;
if (_editCount == 0) {
[self fixSymbols];
}
}
@end
@implementation MPMutableExpression (MPMutableExpressionExtensionMethods)