Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New SPGroup class and little adds in animation classes #41

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions sparrow/src/Classes/SPGroup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// SPGroup.h
// Sparrow
//
// Created by Jérôme Cabanis on 17/03/2015.
// Copyright 2015 Lauraly. All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Simplified BSD License.
//

#import <Foundation/Foundation.h>
#import <Sparrow/SPAnimatable.h>
#import <Sparrow/SPEventDispatcher.h>

/** ------------------------------------------------------------------------------------------------

The SPGroup takes objects that implement SPAnimatable (e.g. `SPTween`s) and executes them, just like
SPJuggler does but objects can be animated sequentially or in parallel.

A SPGroup can be added to a SPJuggler or to an other SPGroup

Furthermore, an object can request to be removed from the SPGroup by dispatching an
`SPEventTypeRemoveFromJuggler` event and SPGroup dispach `SPEventTypeRemoveFromJuggler` event.

SPGroup provide block-based callbacks that are executed in certain phases of it's life time:

- `onStart`: Invoked once when the group starts.
- `onUpdate`: Invoked every time it is advanced.
- `onComplete`: Invoked when all objects are completed.

------------------------------------------------------------------------------------------------- */


@interface SPGroup : SPEventDispatcher <SPAnimatable>

+ (instancetype)parallelGroupWithObjects:(NSArray*)objects;
+ (instancetype)serialGroupWithObjects:(NSArray*)objects;

/// Removes an object from the group. Use this function if the object does not dispatch `SPEventTypeRemoveFromJuggler` events
- (void)removeObject:(id<SPAnimatable>)object;

/// ----------------
/// @name Properties
/// ----------------

/// The delay before the group is started.
@property (nonatomic, assign) double delay;

/// The total life time of the group.
@property (nonatomic, readonly) double elapsedTime;

/// The speed factor adjusts how fast the group's animatables run.
/// For example, a speed factor of 2.0 means the group runs twice as fast.
@property (nonatomic, assign) float speed;

/// Indicates if the group execution is complete.
@property (nonatomic, readonly) BOOL isComplete;

/// A block that will be called when the group starts (after a possible delay).
@property (nonatomic, copy) SPCallbackBlock onStart;

/// A block that will be called each time the group is advanced.
@property (nonatomic, copy) SPCallbackBlock onUpdate;

/// A block that will be called when the group execution is complete.
@property (nonatomic, copy) SPCallbackBlock onComplete;


@end
133 changes: 133 additions & 0 deletions sparrow/src/Classes/SPGroup.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//
// SPGroup.m
// Sparrow
//
// Created by Jérôme on 17/03/2015.
//
//

#import <Sparrow/SPGroup.h>

@implementation SPGroup
{
NSMutableOrderedSet *_objects;
BOOL _serial;
BOOL _started;
BOOL _finished;
}

#pragma mark Initialization

- (instancetype)initWithObjects:(NSArray*)objects serial:(BOOL)serial
{
if ((self = [super init]))
{
_objects = [[NSMutableOrderedSet alloc] init];
_serial = serial;
_elapsedTime = 0.0;
_speed = 1.0f;
_delay = 0;
_started = NO;
_finished = NO;

for (id object in objects)
{
if([object conformsToProtocol:@protocol(SPAnimatable)] && ![_objects containsObject:object])
{
[_objects addObject:object];
if ([(id)object isKindOfClass:[SPEventDispatcher class]])
[(SPEventDispatcher *)object addEventListener:@selector(onRemove:) atObject:self forType:SPEventTypeRemoveFromJuggler];
}
}
}
return self;
}

- (void)dealloc
{
[_objects release];
[super dealloc];
}

+ (instancetype)parallelGroupWithObjects:(NSArray*)objects
{
return [[[SPGroup alloc] initWithObjects:objects serial:NO] autorelease];
}

+(instancetype)serialGroupWithObjects:(NSArray *)objects
{
return [[[SPGroup alloc] initWithObjects:objects serial:YES] autorelease];
}

#pragma mark Methods

- (void)onRemove:(SPEvent *)event
{
[self removeObject:(id<SPAnimatable>)[[event.target retain] autorelease]];
}

- (void)removeObject:(id<SPAnimatable>)object
{
if([_objects containsObject:object])
{
[_objects removeObject:object];

if ([(id)object isKindOfClass:[SPEventDispatcher class]])
[(SPEventDispatcher *)object removeEventListenersAtObject:self forType:SPEventTypeRemoveFromJuggler];
}
}


#pragma mark SPAnimatable

- (void)advanceTime:(double)seconds
{
if(_isComplete) return;

if (seconds < 0.0)
[NSException raise:SPExceptionInvalidOperation format:@"time must be positive"];

seconds *= _speed;

if (seconds > 0.0)
{
_elapsedTime += seconds;

if(_elapsedTime < _delay)
return;

if(!_started)
{
_started = YES;
if (_onStart) _onStart();
}

if(_serial)
{
id<SPAnimatable> object = [_objects firstObject];
if(object)
[object advanceTime:seconds];
}
else
{
// we need work with a copy, since user-code could modify the collection while enumerating
NSArray* objectsCopy = [[_objects array] copy];

for (id<SPAnimatable> object in objectsCopy)
[object advanceTime:seconds];

[objectsCopy release];
}

if (_onUpdate) _onUpdate();

if([_objects count] == 0)
{
_isComplete = YES;
[self dispatchEventWithType:SPEventTypeRemoveFromJuggler];
if (_onComplete) _onComplete();
}
}
}

@end
3 changes: 3 additions & 0 deletions sparrow/src/Classes/SPJuggler.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ NS_ASSUME_NONNULL_BEGIN
/// For example, a speed factor of 2.0 means the juggler runs twice as fast.
@property (nonatomic, assign) float speed;

/// Determines if the juggler is empty.
@property (nonatomic, readonly, getter=isEmpty) BOOL empty;

@end

NS_ASSUME_NONNULL_END
5 changes: 5 additions & 0 deletions sparrow/src/Classes/SPJuggler.m
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ - (BOOL)containsObject:(id<SPAnimatable>)object
return [_objects containsObject:object];
}

-(BOOL)isEmpty
{
return [_objects count] == 0;
}

- (id)delayInvocationAtTarget:(id)target byTime:(double)time
{
SPDelayedInvocation *delayedInv = [SPDelayedInvocation invocationWithTarget:target delay:time];
Expand Down
9 changes: 9 additions & 0 deletions sparrow/src/Classes/SPTween.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ typedef float (^SPTransitionBlock)(float);
/// is not being animated.
- (float)endValueOfProperty:(NSString *)property;

/// Show the target when the tween starts
- (void)show;

/// Hide the target when the tween is complete
- (void)hide;

/// Remove the target from his parent when the tween is complete
- (void)removeFromParent;

/// ----------------
/// @name Properties
/// ----------------
Expand Down
35 changes: 35 additions & 0 deletions sparrow/src/Classes/SPTween.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@

typedef float (*FnPtrTransition) (id, SEL, float);

@protocol VisibleProtocol
-(void)setVisible:(BOOL)visible;
@end

@protocol RemoveFromParentProtocol
- (void)removeFromParent;
@end

@implementation SPTween
{
id _target;
Expand All @@ -37,6 +45,9 @@ @implementation SPTween
BOOL _reverse;
BOOL _roundToInt;
NSInteger _currentCycle;
BOOL _show;
BOOL _hide;
BOOL _removeFromParent;

SPCallbackBlock _onStart;
SPCallbackBlock _onUpdate;
Expand All @@ -59,6 +70,9 @@ - (instancetype)initWithTarget:(id)target time:(double)time transition:(NSString
_repeatCount = 1;
_currentCycle = -1;
_reverse = NO;
_show = NO;
_hide = NO;
_removeFromParent = NO;
self.transition = transition;
}
return self;
Expand Down Expand Up @@ -127,6 +141,21 @@ - (void)scaleTo:(float)scale
[self animateProperty:@"scaleY" targetValue:scale];
}

-(void)show
{
_show = YES;
}

-(void)hide
{
_hide = YES;
}

-(void)removeFromParent
{
_removeFromParent = YES;
}

- (void)fadeTo:(float)alpha
{
[self animateProperty:@"alpha" targetValue:alpha];
Expand Down Expand Up @@ -169,6 +198,8 @@ - (void)advanceTime:(double)time
if (isStarting)
{
_currentCycle++;
if(_show && [_target respondsToSelector:@selector(setVisible:)])
[(id<VisibleProtocol>)_target setVisible:YES];
if (_onStart) _onStart();
}

Expand Down Expand Up @@ -209,6 +240,10 @@ - (void)advanceTime:(double)time
}
else
{
if(_hide && [_target respondsToSelector:@selector(setVisible:)])
[(id<VisibleProtocol>)_target setVisible:NO];
if(_removeFromParent && [_target respondsToSelector:@selector(removeFromParent)])
[(id<RemoveFromParentProtocol>)_target removeFromParent];
[self dispatchEventWithType:SPEventTypeRemoveFromJuggler];
if (_onComplete) _onComplete();
}
Expand Down
1 change: 1 addition & 0 deletions sparrow/src/Classes/Sparrow.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#import <Sparrow/SPEvent.h>
#import <Sparrow/SPEventDispatcher.h>
#import <Sparrow/SPGLTexture.h>
#import <Sparrow/SPGroup.h>
#import <Sparrow/SPJuggler.h>
#import <Sparrow/SPImage.h>
#import <Sparrow/SPIndexData.h>
Expand Down
8 changes: 8 additions & 0 deletions sparrow/src/Sparrow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
02488C2A1AB8A12800912C73 /* SPGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 02488C281AB8A12800912C73 /* SPGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
02488C2B1AB8A12800912C73 /* SPGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 02488C291AB8A12800912C73 /* SPGroup.m */; };
7704F8CF1B7D5A8500E9217F /* SparrowBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 7704F8CC1B7D597F00E9217F /* SparrowBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
7704F8D21B7D5BFD00E9217F /* SparrowBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 7704F8D01B7D5BF200E9217F /* SparrowBase.m */; };
7728E1A91B7A9704007D1BA7 /* SPGLTexture_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7728E1A71B7A9704007D1BA7 /* SPGLTexture_Internal.h */; };
Expand Down Expand Up @@ -401,6 +403,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
02488C281AB8A12800912C73 /* SPGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGroup.h; sourceTree = "<group>"; };
02488C291AB8A12800912C73 /* SPGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPGroup.m; sourceTree = "<group>"; };
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -993,6 +997,8 @@
DED859440FB883EE00D3D7D2 /* SPTransitions.m */,
DE7044750FB62080007F5ECC /* SPTween.h */,
DE7044760FB62080007F5ECC /* SPTween.m */,
02488C281AB8A12800912C73 /* SPGroup.h */,
02488C291AB8A12800912C73 /* SPGroup.m */,
);
name = Animation;
sourceTree = "<group>";
Expand Down Expand Up @@ -1209,6 +1215,7 @@
DE61137A134F8F6C00AB742E /* SPEventDispatcher.h in Headers */,
872F5C3D1880C9E30016071B /* SPFragmentFilter.h in Headers */,
DE61138D134F8FA600AB742E /* SPGLTexture.h in Headers */,
02488C2A1AB8A12800912C73 /* SPGroup.h in Headers */,
DE611388134F8F8300AB742E /* SPImage.h in Headers */,
DE611392134F8FBD00AB742E /* SPJuggler.h in Headers */,
DE611396134F8FBD00AB742E /* SPMacros.h in Headers */,
Expand Down Expand Up @@ -1563,6 +1570,7 @@
DE019C3A1026361200ECB0AC /* SPDelayedInvocation.m in Sources */,
DE019C3B1026363D00ECB0AC /* SPNSExtensions.m in Sources */,
872F5C541880E57A0016071B /* SPColorMatrix.m in Sources */,
02488C2B1AB8A12800912C73 /* SPGroup.m in Sources */,
DE019C3C1026364800ECB0AC /* SPJuggler.m in Sources */,
872F5C501880E2DD0016071B /* SPDisplacementMapFilter.m in Sources */,
872F5C66188236D80016071B /* SPContext.m in Sources */,
Expand Down