<commit_before># Floc Commands
![Floc Commands Logo](http://sschmid.com/Dev/iOS/Libs/Floc-Commands/Floc-Commands-128.png)
[![Build Status](https://travis-ci.org/sschmid/Floc-Commands.png?branch=master)](https://travis-ci.org/sschmid/Floc-Commands)

## Description
Floc Commands is a neat collection of easy-to-use commands for Objective-C.
A command usually contains a small part of synchronous or asynchronous logic and can be chained or nested
as much as you like. Floc Commands comes with a bunch of handy commands such as:

* Sequence Command (executes commands one after another)
* Parallel Command (executes commands all at once)
* Interception Command (executes commands depending on the target command's execution result)
* Block Command (executes a block)
* Master Slave Command (cancels the slave command as soon the master command did execute)
* Repeat Command (executes a command n times)
* Retry Command (retries to execute a command n times, if an error occoured)

All commands are sublcasses of `FLCommand`, which is designed to be used both synchronously or asynchronously.

## How to use Floc Commands
To get started, create a subclass of `FLCommand` and override `execute`. When a command finishes execution,
it must always call `didExecuteWithError:`. If it executed successfully without any errors, you pass nil as an argument
or you can use `didExecute` for convenience. Assign a delegate to respond to `commandWillExecute:`,
`command:didExecuteWithError:` or `commandCancelled:`.

## Fluent API and macros
Floc Commands comes with some nice categories and macros to enable cool stuff like:

```objective-c
FLSQ(dowloadImage, convertImage, applyFilter, upload).stopsOnError(YES).cancelsOnCancel(YES)
            .intercept(showSuccessAlert, showErrorAlert)
            .slave(playJeopardyTheme).keepAlive.execute;
```
In this example `FLSQ` (macro for `FLSequenceCommand`) executes all asynchronous commands one after another. If a
command in the sequence fails for some reason, `showErrorAlert` will be executed, else `showSuccessAlert`.
`playJeopardyTheme` will be executed along with the sequence and gets canceled, as soon as asynchronous
operation is completed. Since we do not have a strong pointer to the command, we call `keepAlive` to ensure the command
will not be deallocated before it's completed.

This example creates a `FLBlockCommand` which repeats 16x followed by a `FLBlockCommand`. The sequence will repeat forever (`-1`)

```objective-c
FLBC(^(FLBlockCommand *command) {
    NSLog(@"na");
    [command performSelector:@selector(didExecute) withObject:nil afterDelay:0.2];
}).repeat(16).flseq(FLBC(^(FLBlockCommand *command) {
    NSLog(@"Batman!");
    [command performSelector:@selector(didExecute) withObject:nil afterDelay:0.2];
})).repeat(-1).keepAlive.execute;
```

There are handy macros for each command type.

## Potential pitfalls
When working with asynchronous commands, you should keep a strong pointer to it, because otherwise it may be
deallocated before it finishes. Alternatively you can call `keepAlive`, so the lifecycle of the command will be
managed for you.

RequestDataCommand might take several seconds to complete, so it's a good idea to assign in to a property to keep
the command alive.

```objective-c
self.cmd = [[[RequesteDataCommand alloc] init] execute];

// or
[[RequesteDataCommand alloc] init].keepAlive.execute;
```

## Examples
Synchronous FLCommand

```objective-c
@implementation HelloWorldCommand

- (void)execute {
    [super execute];

    NSLog(@"Hello world!");

    [self didExecute];
}

@end
```

Asynchronous FLCommand

```objective-c
@implementation SendDataCommand

- (void)execute {
    [super execute];

      // This may take a few seconds...
      [self.server sendData:data onComplete:^(NSError *error) {
          [self didExecuteWithError:error];
      }];
}

@end
```
<commit_msg>Updated readme.<commit_after># Floc Commands
![Floc Commands Logo](http://sschmid.com/Dev/iOS/Libs/Floc-Commands/Floc-Commands-128.png)
[![Build Status](https://travis-ci.org/sschmid/Floc-Commands.png?branch=master)](https://travis-ci.org/sschmid/Floc-Commands)

## Description
Floc Commands is a neat collection of easy-to-use commands for Objective-C.
A command usually contains a small part of synchronous or asynchronous logic and can be chained or nested
as much as you like. Floc Commands comes with a bunch of handy commands such as:

* Sequence Command (executes commands one after another)
* Parallel Command (executes commands all at once)
* Interception Command (executes commands depending on the target command's execution result)
* Block Command (executes a block)
* Master Slave Command (cancels the slave command as soon the master command did execute)
* Repeat Command (executes a command n times)
* Retry Command (retries to execute a command n times, if an error occoured)

All commands are sublcasses of `FLCommand`, which is designed to be used both synchronously or asynchronously.

## How to use Floc Commands
To get started, create a subclass of `FLCommand` and override `execute`. When a command finishes execution,
it must always call `didExecuteWithError:`. If it executed successfully without any errors, you pass `nil` as an argument
or you can use `didExecute` for convenience. Assign a delegate to respond to `commandWillExecute:`,
`command:didExecuteWithError:` or `commandCancelled:`.

## Fluent API and macros
Floc Commands comes with some nice categories and macros to enable cool stuff like:

```objective-c
FLSQ(dowloadImage, convertImage, applyFilter, upload).stopsOnError(YES).cancelsOnCancel(YES).retry(3)
        .intercept(showSuccessAlert, showErrorAlert)
        .slave(playJeopardyTheme.repeat(-1)).keepAlive.execute;
```
In this example `FLSQ` (macro for `FLSequenceCommand`) executes all asynchronous commands one after another and will
retry to execute all commands if any errors occour or a command gets cancelled. If the sequence fails or gets cancelled,
`showErrorAlert` will be executed, else `showSuccessAlert`.
`playJeopardyTheme` will repeat forever (`-1`) and will be executed along with the sequence and gets cancelled, as soon
as asynchronous operation is completed. Since we do not have a strong pointer to the command, we call `keepAlive` to
ensure the command will not be deallocated before it's completed. The lifecycle of the command will be managed for you.

```objective-c
FLBC(^(FLBlockCommand *command) {
    NSLog(@"na");
    [command performSelector:@selector(didExecute) withObject:nil afterDelay:0.2];
}).repeat(16).flseq(FLBC(^(FLBlockCommand *command) {
    NSLog(@"Batman!");
    [command performSelector:@selector(didExecute) withObject:nil afterDelay:0.2];
})).repeat(-1).keepAlive.execute;
```
This example creates a `FLBlockCommand` which repeats 16x followed by another `FLBlockCommand`. The sequence will repeat forever (`-1`)

There are handy macros for each command type. Check them out!
See [FLCommand+Floc.h](https://github.com/sschmid/Floc-Commands/blob/master/Floc-Commands/Classes/Additions/FLCommand%2BFloc.h)

## Potential pitfalls
When working with asynchronous commands, you should keep a strong pointer to it, because otherwise it may be
deallocated before it finishes. Alternatively you can call `keepAlive`, so the lifecycle of the command will be
managed for you.

RequestDataCommand might take several seconds to complete, so it's a good idea to assign in to a property to keep
the command alive.

```objective-c
self.requestCommand = [[[RequesteDataCommand alloc] init] execute];

// or
[[RequesteDataCommand alloc] init].keepAlive.execute;
```

## Examples
Synchronous FLCommand

```objective-c
@implementation HelloWorldCommand

- (void)execute {
    [super execute];

    NSLog(@"Hello world!");

    [self didExecute];
}

@end
```

Asynchronous FLCommand

```objective-c
@implementation SendDataCommand

- (void)execute {
    [super execute];

      // This may take a few seconds...
      [self.service sendData:data onComplete:^(NSError *error) {
          [self didExecuteWithError:error];
      }];
}

- (void)cancel {
    [self.service closeConnection];
    [super cancel];
}

@end
```

{'fraction_non_alphanumeric': 0.09243388834476005, 'fraction_numerical': 0.003672869735553379, 'mean_word_length': 4.928156748911466, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2287394', 'n_tokens_mistral': 2372, 'n_tokens_neox': 2256, 'n_words': 917}