Archived
1

Added Documentation

This commit is contained in:
Kim Wittenburg
2014-12-17 22:04:49 +01:00
parent 8f1f730358
commit 7f6ee6e118
31 changed files with 1141 additions and 533 deletions

View File

@@ -6,14 +6,62 @@
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPExpressionElement.h"
#import "MPExpression.h"
/*!
@header
<code>MPFunction</code> is a half abstract class that is designed to be
subclassed. Subclasses of the <code>MPFunction</code> class (subsequently called
<i>functions</i>) need to regard the following guidelines:
1. In their header file functions should declare <code>readwrite,
nonatomic</code> properties for every child (subexpression) they have.
2. For every public child accessor there should be one use of the
<code>@link MPFunctionAccessorImplementation@/link</code> macro in the
implementation file. See the documentation on the macro for details.
3. Functions must override the <code>@link childrenAccessors@/link</code> method
returning the KVC compatible names of the publicly declared property accessors
4. Functions must also override the <code>@link functionTermClass@/link</code>
method returning a <code>Class</code> that can evaluate the function. See the
documentation on that method for details.
5. Optionally functions can implement
<code>@link expectsVariableDefinitionInChildAtIndex:@/link</code> if one of
its children is supposed to contain a variable definition.
6. Functions should also override the <code>NSObject</code> method
<code>description</code>. Although this is not a requirement it
is strongly recommended.
Functions play an important role in the <i>expression tree</i>. For details on
the that subject see the documentation for <code>@link
MPExpression@/link</code>.
@note
None of the children of a function may be <code>nil</code> at any time.
*/
/* 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
@abstract This macro implements the setter of a previously declared
property of a <code>MPFunction</code> subclass.
@discussion Overriding the default setter implementation 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. If you need to implement additional
custom behaviour in a property setter it is recommended that you
copy the content of the macro.
@param Accessor
The capitalized name of the property to be implemented. This is
used for the name of the method: <code>set...</code>.
@param variableName
The name of the instance variable that backs the property.
Normally this is the same as the name of the property prefixed
with an underscore.
*/
#define MPFunctionAccessorImplementation(Accessor, variableName) \
- (void)set##Accessor:(MPExpression *)value \
@@ -32,25 +80,15 @@
/*!
@class MPFunction
@brief The @c MPFunction class represents a mathematical function.
@abstract The <code>MPFunction</code> class represents a mathematical function.
@discussion A mathematical function can be anything that exceeds the
graphical capability of text.
graphical capability of text. Functions like <code>sin</code>,
<code>cos</code> or <code>ln</code> are not considered functions
in this context because they can be represented by text.
*/
@interface MPFunction : NSObject <NSCoding, NSCopying, MPExpressionElement>
#pragma mark Properties
/* 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
/*!
@methodgroup Working With the Expression Tree
@@ -59,86 +97,85 @@
/*!
@property parent
@brief The receiver's parent.
@abstract 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.
when the function is added to or removed from an expression.
@note If you need to know when a function is added to or removed from
an expression you can observe this property.
an expression you can observe this property using KVO.
@return The parent of the receiver or @c nil if the receiver does not
have a parent.
@return The parent of the receiver or <code>nil</code> 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.
@abstract 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.
@return The root expression from the receiver's expression tree or
<code>nil</code> if this function does not have a parent.
*/
- (MPExpression *)rootExpression;
/*!
@method indexPath
@brief Returns the index path of the receiver in the expression tree.
@abstract 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.
@discussion The index path contains the indexes (starting from the root
expression of the receiver's expression tree) that lead to the
receiver. The indexes are expressed in the element reference
frame.
@return The index path of the receiver in the expression tree or @c nil
if this function does not have a parent.
@return The index path of the receiver in the expression tree or
<code>nil</code> if this function does not have a parent.
*/
- (NSIndexPath *)indexPath;
/*!
@method numberOfChildren
@brief Returns the number of children the receiver has.
@abstract 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.
@return The number of children the receiving function has.
*/
- (NSUInteger)numberOfChildren;
/*!
@method childAtIndex:
@brief Returns the child at the specified index.
@abstract Returns the child at the specified index.
@discussion The ordering of children is determined by the order of the
children returned from the @c -childrenAccessors method.
child accessors as returned from the
<code>@link childrenAccessors@/link</code> method.
@param index
The index of the requested child.
@return The expression that corresponds to the child at @c index.
@return The expression that corresponds to the child at
<code>index</code>.
*/
- (MPExpression *)childAtIndex:(NSUInteger)index;
/*!
@method setChild:atIndex:
@brief Sets the child at the specified index.
@abstract Sets the child at the specified index.
@discussion Although this method does @b not call the respective accessor
@discussion Although this method does <b>not</b> call the respective accessor
methods it behaves exactly as the setter method implemented using
the @c MPFunctionAccessorImplementation macro.
the <code>@link MPFunctionAccessorImplementation@/link</code>
macro.
@param child
The child that should replace the previous one.
@@ -152,10 +189,10 @@
/*!
@method children
@brief Returns the receiver's children.
@abstract Returns the receiver's children.
@discussion The ordering of the children is the same as in the array returned
from @c -childrenAccessors.
from <code>@link childrenAccessors@/link</code>.
@return An array containing all the function's children.
*/
@@ -164,27 +201,29 @@
/*!
@method indexOfChild:
@brief Returns the index of @c child in the receiver.
@abstract Returns the index of <code>child</code> 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.
@return The index of <code>child</code> or <code>NSNotFound</code> if
none of the receiver's children is equal to <code>child</code>.
*/
- (NSUInteger)indexOfChild:(MPExpression *)child;
/*!
@method elementAtIndexPath:
@brief Returns the element at the specified index path.
@abstract 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.
@discussion This method finds the elements at the respective indexes starting
at the root expression from the receiver's expression tree.
The returned object can be a <code>NSString</code>, a
<code>MPFunction</code> or a <code>@link
MPExpression@/link</code> instance depending on the specified
<code>indexPath</code>. If any of the indexes exceed the bounds
of the respective receiver a <code>NSRangeException</code> is
raised.
If the index path does not contain any indexes the receiver
itself is returned.
@@ -193,9 +232,10 @@
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.
@return The element located at <code>indexPath</code>. The element is not
copied before it is returned. Be aware of the fact that any
mutations made to the returned object will update the receiver's
expression tree to reflect the change.
*/
- (id)elementAtIndexPath:(NSIndexPath *)indexPath;
@@ -208,11 +248,11 @@
/*!
@method didChangeElementsInRangePath:replacementLength:
@brief Notification method that is called if one of the children was
mutated.
@abstract This Notification message is sent automatically from the receiver
to itself if one of its children was mutated or changed.
@discussion This method is also called when one of the children is changed
via one of the accessor methods.
@discussion This method should also be 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
@@ -229,12 +269,13 @@
/*!
@method didChangeChildAtIndex:
@brief Convenience method that calls @c
-didChangeElementsInRangePath:replacementLength:
@abstract Convenience method that calls
<code>@link
didChangeElementsInRangePath:replacementLength:@/link</code>
@discussion This method is automatically called when one of the children is
changed using one of the accessor methods or @c
-setChild:atIndex:.
changed using one of the accessor methods or
<code>@link setChild:atIndex:@/link</code>.
@param index
The index of the child that was changed.
@@ -250,20 +291,21 @@
/*!
@method expectsVariableDefinitionInChildAtIndex:
@brief Returns whether the child at @c anIndex is supposed to contain a
variable definition.
@abstract Returns whether the child at <code>anIndex</code> is supposed to
contain a variable definition.
@discussion This method is automatically called during expression parsing.
@discussion This method is automatically called during the parsing process.
You can override this method to opt into the default behaviour.
If you override this method you do not need to call super.
The default implementation just returns @c NO for every index.
The default implementation just returns <code>NO</code> for every
index.
@param anIndex
The index of the child to check.
@return @c YES if the child at @c anIndex is supposed to contain a
variable definition, @c NO otherwise.
@return <code>YES</code> if the child at <code>anIndex</code> is supposed
to contain a variable definition, <code>NO</code> otherwise.
*/
- (BOOL)expectsVariableDefinitionInChildAtIndex:(NSUInteger)anIndex;
@@ -272,22 +314,16 @@
/*!
@category MPFunction (MPSubcalssOverride)
@brief The methods in this category must be implemented by any concrete
subclasses of @c MPFunction.
@category MPFunction (MPSubclassOverride)
@abstract The methods in this category must be implemented by any concrete
subclasses of <code>MPFunction</code>.
@discussion @c MPFunction does not implement the functions itself but calls
@discussion <code>MPFunction</code> 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)
/* In Addition to the methods listed below MPFunction subclasses should also
* override the NSObject method -description.
* Also -expectsVariabledefinitionInChildAtIndex: can be overridden if one of the
* children should contain a variable definition.
*/
#pragma mark Working With the Expression Tree
/*!
@methodgroup Working With the Expression Tree
@@ -296,11 +332,9 @@
/*!
@method childrenAccessors
@brief Returns the names of the children properties.
@abstract Returns the names of the children properties as strings.
@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.
@discussion All objects in the returned array must be strings.
@return An array of strings describing the names of children a function
has.
@@ -316,14 +350,18 @@
/*!
@method functionTermClass
@brief Returns the class that represents the receiver's evaluation
@abstract Returns the class that represents the receiver's evaluation
behaviour.
@discussion The class returned must be a subclass of @c MPFunctionTerm. That
class must not implement a custom initializer.
@discussion Subclasses of <code>MPFunction</code> can (like
<code>@link MPExpression@/link</code>) not evaluate themselves.
Instead this method is called on every function. The returned
class must be a valid subclass of <code>@link
//apple_ref/occ/cl/MPFunctionTerm@/link</code>. It will be
instanciated using the <code>init</code> method.
@return The @c MPFunctionTerm subclass that can evaluate instances of the
receiver's class.
@return The <code>@link //apple_ref/occ/cl/MPFunctionTerm@/link</code>
subclass that can evaluate instances of the receiver's class.
*/
- (Class)functionTermClass;