tef-animation 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,25 @@ require_relative 'SheetSequence.rb'
6
6
 
7
7
  module TEF
8
8
  module Sequencing
9
+ # Sequene Player class.
10
+ #
11
+ # This class is meant as a easy means to play {BaseSequence}s.
12
+ # It allows the user to start and stop sequences, play them in parallel,
13
+ # or overwrite them.
14
+ #
15
+ # Register hooks to be called after an execution step with {#after_exec}.
16
+ #
17
+ # Start playing a sequence by using {#[]=}, then use {#delete} to stop
18
+ # it prematurely.
19
+ #
20
+ # @todo Add pausing of sequences. Requires the BaseSequence to have a
21
+ # time conversion built-in as well.
9
22
  class Player
23
+
24
+ # Initialize a player instance
25
+ #
26
+ # It can immediately be used to play {BaseSequence}s or {Sheet}s, though
27
+ # {#after_exec} callbacks should first be registered.
10
28
  def initialize()
11
29
  @activeSequences = {}
12
30
  @sequenceMutex = Mutex.new
@@ -24,10 +42,31 @@ module TEF
24
42
  @playThread.abort_on_exception = true
25
43
  end
26
44
 
45
+ # Add a callback to be executed after a animation step.
46
+ #
47
+ # The block passed to this function will be executed after each
48
+ # {EventCollector#execute!}, i.e. after every tick of the animation
49
+ # system.
50
+ # This makes it possible to connect it to the Animation system,
51
+ # for example by calling {Animation::Handler#update_tick},
52
+ # as well as the parameter stack by calling
53
+ # {ParameterStack::Stack#process_changes}
27
54
  def after_exec(&block)
28
55
  @post_exec_cbs << block if block_given?
29
56
  end
30
57
 
58
+ # Insert and start a new program.
59
+ #
60
+ # This will:
61
+ # - Stop and tear the currently playing program under 'key' down.
62
+ # - Instantiate a {SheetSequence} IF the program is a {Sheet}
63
+ # - Immediately start playing the new program.
64
+ #
65
+ # The inserted program is returned.
66
+ # {#delete} can be used to stop a given program.
67
+ #
68
+ # @param key Arbitrary key to identify the program with.
69
+ # @param [BaseSequence, Sheet] program Program to start playing.
31
70
  def []=(key, program)
32
71
  @sequenceMutex.synchronize do
33
72
  if @activeSequences[key]
@@ -35,7 +74,6 @@ module TEF
35
74
  end
36
75
 
37
76
  if program.is_a? Sheet
38
- puts "Inited sheet with start at #{Time.now()}"
39
77
  program = SheetSequence.new(Time.now(), 1, sheet: program)
40
78
  end
41
79
 
@@ -48,6 +86,8 @@ module TEF
48
86
  program
49
87
  end
50
88
 
89
+ # Delete a given program by its key.
90
+ # This will stop and tear the specified program down.
51
91
  def delete(key)
52
92
  @sequenceMutex.synchronize do
53
93
  if @activeSequences[key]
@@ -1,16 +1,51 @@
1
1
 
2
+ require_relative 'EventCollector.rb'
2
3
 
3
4
  module TEF
4
5
  module Sequencing
6
+ # Sheet class
7
+ #
8
+ # This class is meant as a container for the minimum
9
+ # amount of information necessary to instantiate a {SheetSequence}.
10
+ #
11
+ # It provides a clean and easy way for the user to define
12
+ # a sequence of events, as well as minimally necessary information
13
+ # such as the speed of the sequence or the starting and ending
14
+ # times.
5
15
  class Sheet
16
+ # @return [Numeric] The local starting time. Defaults to
17
+ # 0, i.e the sheet will start playing immediately.
18
+ # This does not affect the actual time scaling, but instead
19
+ # is merely used to know when to instantiate the {SheetSequence}
6
20
  attr_accessor :start_time
21
+
22
+ # @return [Numeric] The local ending-time. Defaults to nil, i.e.
23
+ # it will be auto-determined by the notes in the sheet.
24
+ # Affects when the sheet is torn down and stops
25
+ # execution!
7
26
  attr_accessor :end_time
8
27
 
28
+ # @return [Numeric, nil] Tempo of the sheet. Defines the execution
29
+ # speed in BPM. If left nil, the execution speed of the parent
30
+ # sheet is used.
9
31
  attr_accessor :tempo
10
32
 
33
+ # @return [nil, Proc] Block to call when setting up the {SheetSequence}.
34
+ # This is the main way of letting the user configure the {SheetSequence},
35
+ # as this block is called from the context of the sheet itself.
36
+ # Look at the functions of the Sheet Sequence for more details.
37
+ #
38
+ # @see SheetSequence#at
39
+ # @see SheetSequence#after
40
+ # @see SheetSequence#play
11
41
  attr_reader :setup_block
12
42
  attr_reader :teardown_block
13
43
 
44
+ # Initialize a new Sheet.
45
+ #
46
+ # The user should configure the sheet by writing into
47
+ # {#start_time}, {#end_time} and by supplying at least a
48
+ # {#sequence}
14
49
  def initialize()
15
50
  @start_time = 0;
16
51
  @end_time = nil;
@@ -21,10 +56,23 @@ module TEF
21
56
  @teardown_block = nil;
22
57
  end
23
58
 
59
+ # Configure a block to call when setting up the {SheetSequence}.
60
+ # This is the main way of letting the user configure the {SheetSequence},
61
+ # as this block is called from the context of the sheet itself.
62
+ # Look at the functions of the Sheet Sequence for more details.
63
+ #
64
+ # @see SheetSequence#at
65
+ # @see SheetSequence#after
66
+ # @see SheetSequence#play
24
67
  def sequence(&block)
25
68
  @setup_block = block;
26
69
  end
27
70
 
71
+ # Configure the block to call when the {SheetSequence} is about to
72
+ # be torn down. Use this to stop or delete any resources allocated
73
+ # to the sheet.
74
+ #
75
+ # Guaranteed to always be called.
28
76
  def teardown(&block)
29
77
  @teardown_block = block;
30
78
  end
@@ -4,7 +4,25 @@ require_relative 'Sheet.rb'
4
4
 
5
5
  module TEF
6
6
  module Sequencing
7
+ # Sheet Sequence class.
8
+ #
9
+ # This is the main way for the user to specify an exact sequence of events
10
+ # to execute. It is construced with the help of a {Sheet}, which
11
+ # acts as specification for this Sheet Sequence.
12
+ #
13
+ # Think of the {Sheet} as being the script for a play or movie, while
14
+ # the {SheetSequence} has the job of actually performing everything.
7
15
  class SheetSequence < BaseSequence
16
+
17
+ # Initialize a SheetSequence.
18
+ #
19
+ # This is mostly done via {Player#[]=} by passing a {Sheet}.
20
+ # However, a sequence can also be manually instantiated.
21
+ #
22
+ # After initialization, the sheet's {Sheet#setup_block} is called
23
+ # to fill this SheetSequence with actual content.
24
+ # The user may also call {#at} and {#after} manually to add additional
25
+ # events.
8
26
  def initialize(offset, slope, **options)
9
27
  super(offset, slope, **options);
10
28
 
@@ -55,6 +73,23 @@ module TEF
55
73
  super();
56
74
  end
57
75
 
76
+ # Insert an event or subsheet into the event list.
77
+ #
78
+ # This is the main way of adding events to this sequence.
79
+ # Each call to the function will insert a new event at the specified
80
+ # time, which will call the passed block.
81
+ # If, instead, a parameter called :sheet or :sequence is passed,
82
+ # instead the the passed sequence will be instantiated and
83
+ # added to the list of programs.
84
+ # Any further options are directly passed to the constructor
85
+ # of the class specified by the :sequence parameter
86
+ #
87
+ # If a block was passed, it will be instance_exec'd at the specified
88
+ # time.
89
+ #
90
+ # Note that any used or created resources shall be destroyed in
91
+ # the {Sheet#teardown} block. Sub-Sequences as well as notes
92
+ # played by {#play} are automatically torn down.
58
93
  def at(time, **options, &block)
59
94
  @latest_note_time = time;
60
95
 
@@ -82,10 +117,22 @@ module TEF
82
117
  @notes.insert((i || -1), new_event);
83
118
  end
84
119
 
120
+ # Similar to {#at}, but specifies time relative to the
121
+ # last event time.
122
+ # @see #at
85
123
  def after(time, **options, &block)
86
124
  at(time + (@latest_note_time || 0) , **options, &block);
87
125
  end
88
126
 
127
+ # Play a music file, using `play`
128
+ #
129
+ # The PID of the music playing task is saved, and the process
130
+ # will be killed when this sheet is torn down. The user does not
131
+ # have to do anything else, but may choose to prematurely kill
132
+ # the playback by using {#kill}
133
+ #
134
+ # @param [String] music_piece Path of the file to play.
135
+ # @return [Numeric] The PID of the spawned process.
89
136
  def play(music_piece, volume = 0.3)
90
137
  play_pid = spawn(*%W{play -q --volume #{volume} #{music_piece}});
91
138
 
@@ -98,11 +145,12 @@ module TEF
98
145
  play_pid
99
146
  end
100
147
 
148
+ # Shorthand to kill
101
149
  def kill(pid)
102
150
  Process.kill('QUIT', pid);
103
151
  end
104
152
 
105
- def overload_append_events(collector)
153
+ private def overload_append_events(collector)
106
154
  i = 0
107
155
  loop do
108
156
  next_program = @subprograms[i]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tef-animation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - TheSystem