Game-EnergyLoop

 view release on metacpan or  search on metacpan

eg/rhythm.pl  view on Meta::CPAN

use Game::EnergyLoop;
use List::UtilsBy qw(rev_nsort_by);
use MIDI;
use Object::Pad;

my @events;
my $out_file = shift // 'out.midi';

class Timer {
    field $name :param :reader = "none";
    field $alive :reader = 1;
    field $callback :param :writer;
    field $energy :param            = 96;
    field $cur_energy               = 0;
    field $start :param             = 0;
    field $priority :param :reader  = 0;
    field $ttl :param               = 1;

    field $channel :param = 0;
    field $pitch :param;
    field $velocity :param = 90;

eg/rhythm.pl  view on Meta::CPAN

        return $cur_energy;
    }

    method enlo_update( $value, $min, $stash ) {
        my $dtime = 0;
        unless ( $stash->{advanced} ) {
            $dtime = $value;
            $stash->{advanced} = 1;
        }
        my $spawn = $callback->( $dtime, $channel, $pitch, $velocity );
        $alive = 0 if --$ttl <= 0;
        $start = 0;
        # when we're next scheduled to run (if still alive)
        return defined $spawn ? ( $energy, $spawn ) : $energy;
    }
}

# Create a note_on event, and schedule a note_off for later.
sub note {
    my ( $dtime, $channel, $pitch, $velocity ) = @_;
    push @events, [ note_on => $dtime, $channel, $pitch, $velocity ];
    return [
        Timer->new(

eg/rhythm.pl  view on Meta::CPAN


sub reorder ($objs) {
    # The priority is so that note_off turn off previous note_on before
    # a new note_on for the same pitch.
    @$objs = rev_nsort_by { $_->priority } @$objs;
}

my $cost;
do {
    $cost    = Game::EnergyLoop::update( \@objects, \&reorder, $stash );
    @objects = grep { $_->alive } @objects;
    $stash->{advanced} = 0;
} while ( $cost < ~0 );

sub make_tracks () { [ MIDI::Track->new( { events => \@events } ) ] }

MIDI::Opus->new(
    { format => 0, ticks => 96, tracks => make_tracks() } )
  ->write_to_file($out_file);



( run in 0.834 second using v1.01-cache-2.11-cpan-39bf76dae61 )