Added Documentation
This commit is contained in:
@@ -8,6 +8,13 @@
|
||||
|
||||
#import "MPExpressionElement.h"
|
||||
|
||||
|
||||
|
||||
/* Use this macro to implement a custom setter for children of custom MPFunction
|
||||
* subclasses. This is necessary to maintain the consistency of the expression
|
||||
* tree. Not implementing a custom setter using this macro or a similar custom
|
||||
* method will lead to unexpected behaviour.
|
||||
*/
|
||||
#define MPFunctionAccessorImplementation(Accessor, variableName) \
|
||||
- (void)set##Accessor:(MPExpression *)value \
|
||||
{ \
|
||||
@@ -17,51 +24,297 @@
|
||||
[self didChangeChildAtIndex:[self indexOfChild:variableName]]; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@class MPFunction, MPExpression, MPRangePath;
|
||||
@protocol MPExpressionElement;
|
||||
|
||||
|
||||
/*!
|
||||
@class MPFunction
|
||||
@brief The @c MPFunction class represents a mathematical function.
|
||||
|
||||
@discussion A mathematical function can be anything that exceeds the
|
||||
graphical capability of text.
|
||||
*/
|
||||
@interface MPFunction : NSObject <NSCoding, NSCopying, MPExpressionElement>
|
||||
|
||||
#pragma mark Creation Methods
|
||||
|
||||
- (instancetype)init;
|
||||
|
||||
#pragma mark Properties
|
||||
// Subclasses should define accessor properties for all sub expressions, which, in the setter, should send didChangeElementAtRangePath:replacementLength: to self with a replacement length of 1.
|
||||
/* Subclasses should define readwrite properties for all child expressions they
|
||||
* can have. In the implementation file the property setter should be overridden
|
||||
* using the @c MPFunctionAccessorImplementation macro. The macro takes two
|
||||
* parameters: The capitalized name of the property and the name of the
|
||||
* property's backing variable (usually the property's name prefixed with an
|
||||
* underscore.
|
||||
*
|
||||
* Note that none of the children may be nil at any time.
|
||||
*/
|
||||
|
||||
|
||||
#pragma mark Working With the Expression Tree
|
||||
@property (nonatomic, weak) MPExpression *parent; // Documentation: Do not set
|
||||
/*!
|
||||
@methodgroup Working With the Expression Tree
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
@property parent
|
||||
@brief The receiver's parent.
|
||||
|
||||
@discussion Expressions and functions are organized in a tree-like structure.
|
||||
Through this property a function's containing expression can be
|
||||
accessed.
|
||||
@warning Do not set this property manually. It will automatically be set
|
||||
when the function is added to an expression.
|
||||
@note If you need to know when a function is added to or removed from
|
||||
an expression you can observe this property.
|
||||
|
||||
@return The parent of the receiver or @c nil if the receiver does not
|
||||
have a parent.
|
||||
*/
|
||||
@property (nonatomic, weak) MPExpression *parent;
|
||||
|
||||
|
||||
/*!
|
||||
@method rootExpression
|
||||
@brief Returns the root expression from the receiver's expression tree.
|
||||
|
||||
@discussion The root expression is the ultimate parent of all expressions and
|
||||
functions in the expression tree. A root expression does not have
|
||||
a parent.
|
||||
|
||||
@return The root expression from the receiver's expression tree or @c nil
|
||||
if this function does not have a parent.
|
||||
*/
|
||||
- (MPExpression *)rootExpression;
|
||||
|
||||
|
||||
/*!
|
||||
@method indexPath
|
||||
@brief Returns the index path of the receiver in the expression tree.
|
||||
|
||||
@discussion The index path is calculated by going up the expression tree
|
||||
collecting the respective index of the receiver. The indexes are
|
||||
expressed in the element reference frame. If any of the indexes
|
||||
exceed the respective receiver's bounds a @c NSRangeException is
|
||||
raised.
|
||||
|
||||
@return The index path of the receiver in the expression tree or @c nil
|
||||
if this function does not have a parent.
|
||||
*/
|
||||
- (NSIndexPath *)indexPath;
|
||||
|
||||
- (NSArray *)childrenAccessors; // Override
|
||||
|
||||
/*!
|
||||
@method numberOfChildren
|
||||
@brief Returns the number of children the receiver has.
|
||||
|
||||
@discussion The number of children must be equal to the number of child
|
||||
accessors as determined by the @c -childrenAccessors method.
|
||||
|
||||
@return The number of children of the receiving function.
|
||||
*/
|
||||
- (NSUInteger)numberOfChildren;
|
||||
|
||||
|
||||
/*!
|
||||
@method childAtIndex:
|
||||
@brief Returns the child at the given index.
|
||||
|
||||
@discussion The ordering of children is determined by the order of the
|
||||
children returned from the @c -childrenAccessors method.
|
||||
|
||||
@param index
|
||||
The index of the requested child.
|
||||
|
||||
@return The expression that corresponds to the child at @c index.
|
||||
*/
|
||||
- (MPExpression *)childAtIndex:(NSUInteger)index;
|
||||
|
||||
|
||||
/*!
|
||||
@method setChild:atIndex:
|
||||
@brief Sets the child at the specified index.
|
||||
|
||||
@discussion Although this method does @b not call the respective accessor
|
||||
methods it behaves exactly as the setter method implemented using
|
||||
the @c MPFunctionAccessorImplementation macro.
|
||||
|
||||
@param child
|
||||
The child that should replace the previous one.
|
||||
|
||||
@param index
|
||||
The index of the child to be replaced.
|
||||
*/
|
||||
- (void)setChild:(MPExpression *)child
|
||||
atIndex:(NSUInteger)index;
|
||||
|
||||
- (NSArray *)children; // Indexes must equal the ones from the other methods
|
||||
|
||||
/*!
|
||||
@method children
|
||||
@brief Returns the receiver's children.
|
||||
|
||||
@discussion The ordering of the children is the same as in the array returned
|
||||
from @c -childrenAccessors.
|
||||
|
||||
@return An array containing all the function's children.
|
||||
*/
|
||||
- (NSArray *)children;
|
||||
|
||||
|
||||
/*!
|
||||
@method indexOfChild:
|
||||
@brief Returns the index of @c child in the receiver.
|
||||
|
||||
@param child
|
||||
The child to be searched.
|
||||
|
||||
@return The index of @c child or @c NSNotFound if none of the receiver's
|
||||
children is equal to @c child.
|
||||
*/
|
||||
- (NSUInteger)indexOfChild:(MPExpression *)child;
|
||||
|
||||
|
||||
/*!
|
||||
@method elementAtIndexPath:
|
||||
@brief Returns the element at the specified index path.
|
||||
|
||||
@discussion This method @em walks down the expression tree (including other
|
||||
functions) using the specified index path and finds the
|
||||
corresponding element. The returned object can be an @c NSString,
|
||||
a @c MPFunction or an @c MPExpression depending on the element @c
|
||||
indexPath points to. If any of the indexes exceed the bounds of
|
||||
the respective receiver an @c NSRangeException is raised.
|
||||
|
||||
If the index path does not contain any indexes the receiver
|
||||
itself is returned.
|
||||
|
||||
@param indexPath
|
||||
The index path the required object is located at. The indexes are
|
||||
expressed in the element reference frame.
|
||||
|
||||
@return The element located at @c indexPath. The element is not copied
|
||||
before it is returned. Be aware of the fact that any mutations
|
||||
made to the returned object are reflected in the receiver.
|
||||
*/
|
||||
- (id)elementAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
#pragma mark Evaluating Functions
|
||||
|
||||
- (BOOL)validate:(NSError *__autoreleasing *)error; // Override
|
||||
- (NSDecimalNumber *)evaluate; // Override
|
||||
#pragma mark Notifications
|
||||
/*!
|
||||
@methodgroup Notifications
|
||||
*/
|
||||
|
||||
#pragma mark Messages
|
||||
|
||||
/*!
|
||||
@method didChangeElementsInRangePath:replacementLength:
|
||||
@brief Notification method that is called if one of the children was
|
||||
mutated.
|
||||
|
||||
@discussion This method is also called when one of the children is changed
|
||||
via one of the accessor methods.
|
||||
|
||||
@param rangePath
|
||||
The location of the change that happened. Because it may have
|
||||
happened somewhere deep down in the expression tree a range path
|
||||
is used.
|
||||
|
||||
@param replacementLength
|
||||
The number of elements that replaced the elements addressed by
|
||||
the range path.
|
||||
*/
|
||||
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength;
|
||||
|
||||
|
||||
/*!
|
||||
@method didChangeChildAtIndex:
|
||||
@brief Convenience method that calls @c
|
||||
-didChangeElementsInRangePath:replacementLength:
|
||||
|
||||
@discussion This method is automatically called when one of the children is
|
||||
changed using one of the accessor methods or @c
|
||||
-setChild:atIndex:.
|
||||
|
||||
@param index
|
||||
The index of the child that was changed.
|
||||
*/
|
||||
- (void)didChangeChildAtIndex:(NSUInteger)index;
|
||||
|
||||
#pragma mark Working With Functions
|
||||
// - (BOOL)isEqualToFunction:(MPFunction *)aFunction; // Override
|
||||
@end
|
||||
|
||||
- (NSString *)description; // Should be overridden
|
||||
- (NSUInteger)hash;
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone;
|
||||
|
||||
/*!
|
||||
@category MPFunction (MPSubcalssOverride)
|
||||
@brief The methods in this category must be implemented by any concrete
|
||||
subclasses of @c MPFunction.
|
||||
|
||||
@discussion @c MPFunction does not implement the functions itself but calls
|
||||
them at various points. If a subclass does not provide
|
||||
implementations your app will most likely crash.
|
||||
*/
|
||||
@interface MPFunction (MPSubclassOverride)
|
||||
|
||||
#pragma mark Working With the Expression Tree
|
||||
/*!
|
||||
@methodgroup Working With the Expression Tree
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
@method childrenAccessors
|
||||
@brief Returns the names of the children properties.
|
||||
|
||||
@discussion A @c MPFunction subclass should declare a public propertiy for
|
||||
every child it can have. This method should return the names as
|
||||
they would be used for key-value-coding.
|
||||
|
||||
@return An array of strings describing the names of children a function
|
||||
has.
|
||||
*/
|
||||
- (NSArray *)childrenAccessors;
|
||||
|
||||
|
||||
#pragma mark Evaluating Functions
|
||||
/*!
|
||||
@methodgroup Evaluating Functions
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
@method validate:
|
||||
@brief Validates the function and all its children for syntax errors.
|
||||
|
||||
@param error
|
||||
If the validation fails this parameter should be set to an
|
||||
appropriate value.
|
||||
|
||||
@return @c YES if the validation was successful, @c NO otherwise.
|
||||
*/
|
||||
- (BOOL)validate:(NSError *__autoreleasing *)error;
|
||||
|
||||
|
||||
/*!
|
||||
@method evaluate:
|
||||
@brief Evaluates the function.
|
||||
|
||||
@discussion Function evaluation should actually perform math. Also the
|
||||
implementation of this method assumes that the function and all
|
||||
children are valid (as determined by the @c -validate: method).
|
||||
|
||||
@param error
|
||||
If a mathematical error occurs it is reflected in this parameter.
|
||||
Depending on the error this method then either returns @c nil or
|
||||
@c NaN.
|
||||
|
||||
@return The result of the evaluation or @c nil or @c NaN if an evaluation
|
||||
error occured (such as a division by @c 0).
|
||||
*/
|
||||
- (NSDecimalNumber *)evaluate:(NSError *__autoreleasing *)error;
|
||||
|
||||
/* In Addition to the above methods MPFunction subclasses should also override
|
||||
* the NSObject methods -description and -hash.
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user