Added Change Notifications to MPExpression, MPMutableExpression and MPFunction
Removed -beginEditing and -endEditing Optimized -fixSymbols Updated Project File
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user