livecode 0.0.8 → 0.1.0
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.
- data/.gitignore +1 -0
- data/README.rdoc +7 -1
- data/VERSION +1 -1
- data/lib/livecode.rb +49 -0
- data/lib/livecode/clock.rb +192 -0
- data/lib/livecode/clock_recipients.rb +81 -0
- data/lib/livecode/delay.rb +31 -0
- data/lib/livecode/extensions/main.rb +13 -0
- data/lib/livecode/extensions/numeric.rb +12 -0
- data/lib/livecode/extensions/object.rb +10 -0
- data/lib/livecode/extensions/string.rb +10 -0
- data/lib/livecode/loader.rb +47 -0
- data/lib/livecode/silenceable.rb +19 -0
- data/lib/livecode/timer.rb +68 -0
- data/lib/livecode_server/scope.rb +4 -0
- data/livecode.gemspec +12 -2
- metadata +12 -2
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
= Livecode: Ruby toolkit for TextMate/OSX
|
2
2
|
|
3
|
-
|
3
|
+
<em>Live coding (sometimes known as 'interactive programming', 'on-the-fly programming', 'just in time programming') is the name given to the process of writing software in realtime as part of a performance. Historically, similar techniques were used to produce early computer art, but recently it has been explored as a more rigorous alternative to laptop DJs who, live coders often feel, lack the charisma and pizzazz of musicians performing live.</em>
|
4
|
+
|
5
|
+
<em>Generally, this practice stages a more general approach: one of interactive programming, of writing (parts of) programs while they run. Traditionally most computer music programs have tended toward the old write/compile/run model which evolved when computers were much less powerful. This approach has locked out code-level innovation by people whose programming skills are more modest. Some programs have gradually integrated real-time controllers and gesturing (for example, MIDI-driven software synthesis and parameter control). Until recently, however, the musician/composer rarely had the capability of real-time modification of program code itself."</em> - http://en.wikipedia.org/wiki/Livecoding#Live_coding
|
6
|
+
|
7
|
+
Livecode is a toolkit for livecoding with Ruby using TextMate on OSX. At the core, it's a server/client setup that'll let you run and modify code in realtime.
|
8
|
+
|
9
|
+
The server and TextMate bundle is functional, I'm currently working on porting over the MIDI code. Watch this space.
|
4
10
|
|
5
11
|
== Installation
|
6
12
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/livecode.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
# = The Livecode library
|
4
|
+
#
|
5
|
+
# To get started, require and include Livecode:
|
6
|
+
#
|
7
|
+
# require 'livecode'
|
8
|
+
# include Livecode
|
9
|
+
#
|
10
|
+
# For your main loop, have a look at Timer, Delay or the more sophisticated Clock class.
|
11
|
+
|
12
|
+
module Livecode
|
13
|
+
LIBRARY_PATH = Pathname.new(File.join(File.dirname(__FILE__))).realpath.to_s
|
14
|
+
unless self.const_defined?('Loader')
|
15
|
+
$:.unshift LIBRARY_PATH
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Bootstrap loader
|
20
|
+
(bootstrap = %w{livecode/loader livecode/extensions/main}).each{|l| require l}
|
21
|
+
self.send(:include, Livecode::Extensions::Main)
|
22
|
+
(bootstrap + [__FILE__]).each{|l| Livecode.loader.add_reloadable(l)}
|
23
|
+
|
24
|
+
# These should all be safe to load multiple times
|
25
|
+
%w{
|
26
|
+
clock
|
27
|
+
clock_recipients
|
28
|
+
delay
|
29
|
+
extensions/numeric
|
30
|
+
extensions/object
|
31
|
+
extensions/string
|
32
|
+
silenceable
|
33
|
+
timer
|
34
|
+
}.each{|l| live_require "livecode/#{l}"}
|
35
|
+
|
36
|
+
# Apply extensions
|
37
|
+
Numeric.send(:include, Livecode::Extensions::Numeric)
|
38
|
+
Object.send(:include, Livecode::Extensions::Object)
|
39
|
+
String.send(:include, Livecode::Extensions::String)
|
40
|
+
|
41
|
+
class NilClass #:nodoc:
|
42
|
+
def chance?; false; end; alias :c? :chance?
|
43
|
+
end
|
44
|
+
class FalseClass #:nodoc:
|
45
|
+
def chance?; false; end; alias :c? :chance?
|
46
|
+
end
|
47
|
+
class TrueClass #:nodoc:
|
48
|
+
def chance?; true; end; alias :c? :chance?
|
49
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
module Livecode
|
2
|
+
|
3
|
+
# = Clock
|
4
|
+
#
|
5
|
+
# Clock is quite literally the beating pulse of Livecode,
|
6
|
+
# providing you with a way to sync up blocks of code.
|
7
|
+
#
|
8
|
+
# == Creating a clock
|
9
|
+
#
|
10
|
+
# Clock.new takes two options; :tempo and :resolution.
|
11
|
+
# Tempo should be self-explanatory, and is measured in beats
|
12
|
+
# per minute (BPM). The default is 120 BPM.
|
13
|
+
# Resolution is the number of ticks per beat. The default
|
14
|
+
# is 4, which is the equivalent of 16th notes.
|
15
|
+
#
|
16
|
+
# clock = Clock.new(:tempo => 120, :resolution => 4)
|
17
|
+
#
|
18
|
+
# == Control
|
19
|
+
#
|
20
|
+
# clock.start # Starts the clock
|
21
|
+
# clock.stop # Stops the clock, resets the tick
|
22
|
+
# clock.pause # Pauses the clock, does not reset the tick
|
23
|
+
# clock.restart # Restarts the clock
|
24
|
+
# clock.running? # Check if the clock is running
|
25
|
+
#
|
26
|
+
# If you lose track of your variables, you can use
|
27
|
+
# <tt>Clock.stop_all</tt> to stop all clocks.
|
28
|
+
#
|
29
|
+
# == Ticks
|
30
|
+
#
|
31
|
+
# The clock is based on ticks, which is simply an incrementing counter.
|
32
|
+
# <tt>clock.tick</tt> will return the current tick, while
|
33
|
+
# <tt>clock.tick_length</tt> will return the length of one tick expressed
|
34
|
+
# in seconds.
|
35
|
+
#
|
36
|
+
# The modulo operator is quite handy for turning ticks into rythmical
|
37
|
+
# structures:
|
38
|
+
#
|
39
|
+
# bassdrum.play if clock.tick % 4 == 0 # Plays the bass drum on every beat
|
40
|
+
# snare.play if clock.tick % 8 == 4 # ..and the snare on every other beat
|
41
|
+
#
|
42
|
+
# == Recipients
|
43
|
+
#
|
44
|
+
# A recipient is a callback that will be triggered on every tick. Each
|
45
|
+
# recipient must have a unique name, and there's a few ways to attach them.
|
46
|
+
# The following examples all do the same:
|
47
|
+
#
|
48
|
+
# clock.recipients.add(:hihat, proc{|clock| hihat.play})
|
49
|
+
# clock.recipients[:hihat] = proc{|clock| hihat.play})
|
50
|
+
# clock.recipients.hihat = proc{|clock| hihat.play}
|
51
|
+
# clock.recipients.hihat{|clock| hihat.play}
|
52
|
+
# clock[:hihat] = proc{|clock| hihat.play}
|
53
|
+
# clock.hihat = proc{|clock| hihat.play}
|
54
|
+
# clock.hihat{|clock| hihat.play}
|
55
|
+
#
|
56
|
+
# To remove a recipient, simply unset it:
|
57
|
+
#
|
58
|
+
# clock.hihat = false
|
59
|
+
#
|
60
|
+
# Furthermore, recipients can be muted, temporarily disabling them:
|
61
|
+
#
|
62
|
+
# clock.mute(:bassdrum, :snare) # Mutes the bass drum and snare
|
63
|
+
# clock.solo(:synth, :bass) # Solos the synth and bass
|
64
|
+
# clock.enable_all # Re-enables all recipients
|
65
|
+
#
|
66
|
+
# Remember: The callbacks are executed sequentially. If your callback takes
|
67
|
+
# more than a split second, you should wrap the code in it's own thread to
|
68
|
+
# allow for parallel processing.
|
69
|
+
#
|
70
|
+
# Clock will also try to compensate for the run time of your code in
|
71
|
+
# order to stay in sync.
|
72
|
+
|
73
|
+
class Clock
|
74
|
+
class << self
|
75
|
+
# Register a new clock.
|
76
|
+
def register(clock)
|
77
|
+
clocks << clock
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return all registered clocks.
|
81
|
+
def clocks
|
82
|
+
@@clocks ||= []
|
83
|
+
end
|
84
|
+
|
85
|
+
# Stop all clocks.
|
86
|
+
def stop_all
|
87
|
+
clocks.each{|clock| clock.stop}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
attr_accessor :tempo, :resolution
|
92
|
+
attr_reader :tick
|
93
|
+
|
94
|
+
def initialize(options={})
|
95
|
+
@tempo = options[:tempo] || 120
|
96
|
+
@resolution = options[:resolution] || 4
|
97
|
+
@tick = -1
|
98
|
+
@thread = nil
|
99
|
+
@running = false
|
100
|
+
@recipients = ClockRecipients.new
|
101
|
+
Clock.register(self)
|
102
|
+
end
|
103
|
+
|
104
|
+
public
|
105
|
+
|
106
|
+
# Clock recipients
|
107
|
+
def recipients; @recipients; end
|
108
|
+
alias :r :recipients
|
109
|
+
|
110
|
+
# Length of a single tick (in seconds).
|
111
|
+
def tick_length
|
112
|
+
tl = (1/(@tempo.to_f/60))/@resolution
|
113
|
+
tl = 0.00000001 if tl <= 0
|
114
|
+
tl
|
115
|
+
end
|
116
|
+
alias :tl :tick_length
|
117
|
+
|
118
|
+
# Start the clock. Restarts if the clock is already running.
|
119
|
+
def start
|
120
|
+
@running = true
|
121
|
+
stop_thread
|
122
|
+
start_thread
|
123
|
+
self
|
124
|
+
end
|
125
|
+
alias :play :start
|
126
|
+
|
127
|
+
# Stop the clock.
|
128
|
+
def stop
|
129
|
+
stop_thread
|
130
|
+
@tick = -1
|
131
|
+
@running = false
|
132
|
+
self
|
133
|
+
end
|
134
|
+
|
135
|
+
# Pause the clock.
|
136
|
+
def pause
|
137
|
+
@running = false
|
138
|
+
self
|
139
|
+
end
|
140
|
+
|
141
|
+
# Restart the clock.
|
142
|
+
def restart
|
143
|
+
@tick = -1
|
144
|
+
start
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns true if the clock is running.
|
148
|
+
def running?
|
149
|
+
@running ? true : false
|
150
|
+
end
|
151
|
+
|
152
|
+
# Run next tick.
|
153
|
+
def tick!
|
154
|
+
@tick += 1
|
155
|
+
recipients.each do |r|; unless r.silenced?
|
156
|
+
if r.kind_of?(Proc)
|
157
|
+
r.call(self)
|
158
|
+
elsif r.respond_to?(:tick)
|
159
|
+
r.tick(self)
|
160
|
+
end
|
161
|
+
end; end
|
162
|
+
end
|
163
|
+
|
164
|
+
def method_missing(method_name, *args, &block)
|
165
|
+
self.recipients.send(method_name, *args, &block)
|
166
|
+
end
|
167
|
+
|
168
|
+
protected
|
169
|
+
|
170
|
+
# Stop the clock thread.
|
171
|
+
def stop_thread
|
172
|
+
if @thread
|
173
|
+
@thread.exit
|
174
|
+
@thread = nil
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Start the clock thread.
|
179
|
+
def start_thread
|
180
|
+
clock = self
|
181
|
+
@thread ||= Thread.new do
|
182
|
+
next_time = Time.now
|
183
|
+
while @running
|
184
|
+
clock.tick!
|
185
|
+
next_time += tick_length
|
186
|
+
sleep_time = next_time - Time.now
|
187
|
+
sleep(sleep_time) if sleep_time > 0
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Livecode
|
2
|
+
|
3
|
+
# Recipients hash for the clock, see Clock for documentation.
|
4
|
+
|
5
|
+
class ClockRecipients
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@collection = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def each
|
13
|
+
@collection.each{|key,r| yield r}
|
14
|
+
end
|
15
|
+
|
16
|
+
def each_with_index
|
17
|
+
@collection.each{|key,r| yield key, r}
|
18
|
+
end
|
19
|
+
|
20
|
+
def keys
|
21
|
+
@collection.map{|k,o| k}
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_key?(key)
|
25
|
+
(@collection.keys.map{|k| k}.include?(key.to_sym)) ? true : false
|
26
|
+
end
|
27
|
+
|
28
|
+
def set(key, obj=nil, &block)
|
29
|
+
obj = block if block_given?
|
30
|
+
if obj
|
31
|
+
@collection[key.to_sym] = Silenceable.apply( obj )
|
32
|
+
elsif has_key?(key)
|
33
|
+
@collection.delete(key.to_sym)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias :add :set
|
37
|
+
alias :attach :set
|
38
|
+
alias :[]= :set
|
39
|
+
|
40
|
+
def get(key)
|
41
|
+
return nil unless self.has_key?(key)
|
42
|
+
@collection[key.to_sym]
|
43
|
+
end
|
44
|
+
alias :[] :get
|
45
|
+
|
46
|
+
def method_missing(method_sym, *args, &block)
|
47
|
+
method_name = method_sym.to_s
|
48
|
+
if method_name =~ /=$/
|
49
|
+
self.set(method_name.gsub(/=$/, ''), *args)
|
50
|
+
elsif block_given?
|
51
|
+
self.set(method_name, *args, &block)
|
52
|
+
else
|
53
|
+
return nil unless self.has_key?(method_name)
|
54
|
+
self.get(method_name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def silence(*keys)
|
59
|
+
keys.each{|k| self[k].silenced = true}
|
60
|
+
end
|
61
|
+
alias :mute :silence
|
62
|
+
|
63
|
+
def silence_all
|
64
|
+
each_with_index{|k,o| self[k].silenced = true}
|
65
|
+
end
|
66
|
+
alias :mute_all :silence_all
|
67
|
+
|
68
|
+
def solo(*keys)
|
69
|
+
silence_all
|
70
|
+
keys.each{|k| self[k].silenced = false}
|
71
|
+
end
|
72
|
+
alias :play :solo
|
73
|
+
|
74
|
+
def enable_all
|
75
|
+
each_with_index{|k,o| self[k].silenced = false}
|
76
|
+
end
|
77
|
+
alias :play_all :enable_all
|
78
|
+
alias :unsolo :enable_all
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Livecode
|
2
|
+
|
3
|
+
# = Delay
|
4
|
+
#
|
5
|
+
# Delay lets you schedule a block for later.
|
6
|
+
#
|
7
|
+
# Delay.new(1000){puts "One second later"}
|
8
|
+
# later = proc{puts "I am a proc"}
|
9
|
+
# Delay.new(500, later)
|
10
|
+
|
11
|
+
class Delay
|
12
|
+
attr_accessor :time, :proc
|
13
|
+
|
14
|
+
# Time is specified in milliseconds
|
15
|
+
def initialize(time, proc=nil, &block)
|
16
|
+
@time = time || 1
|
17
|
+
if proc
|
18
|
+
@proc = proc
|
19
|
+
elsif block_given?
|
20
|
+
@proc = block
|
21
|
+
end
|
22
|
+
Silenceable.apply(@proc) if @proc
|
23
|
+
if @proc && !@proc.silenced?
|
24
|
+
@thread = Thread.new do
|
25
|
+
sleep @time.to_f / 1000
|
26
|
+
@proc.call
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Livecode
|
2
|
+
|
3
|
+
# Handles (re)loading of library files, which is mostly useful for development.
|
4
|
+
|
5
|
+
class Loader
|
6
|
+
attr_accessor :reloadable_files
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@reloadable_files = []
|
10
|
+
@reloading = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_reloadable(file)
|
14
|
+
file = parse_path(file)
|
15
|
+
@reloadable_files << file unless @reloadable_files.include?(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_file(file, force=false)
|
19
|
+
file = parse_path(file)
|
20
|
+
return false if @reloading && !force && @reloadable_files.include?(file)
|
21
|
+
add_reloadable file
|
22
|
+
load("#{file}.rb")
|
23
|
+
end
|
24
|
+
|
25
|
+
def reload!
|
26
|
+
puts "Reloading: #{@reloadable_files.inspect}"
|
27
|
+
@reloading = true
|
28
|
+
old_v = $-v; $-v = nil # Temporarily disable warnings
|
29
|
+
results = @reloadable_files.map{ |f| load_file( f, true ) }
|
30
|
+
$-v = old_v # Re-enable eventual warnings
|
31
|
+
@reloading = false
|
32
|
+
return results
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_path(path)
|
36
|
+
path.gsub(/\.rb$/, '').gsub(/^\.\//, '')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
41
|
+
attr_accessor :loader
|
42
|
+
def loader
|
43
|
+
@loader ||= Loader.new
|
44
|
+
@loader
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Livecode
|
2
|
+
|
3
|
+
# Silenceable lets you mute procs and blocks when used by Timer and Clock.
|
4
|
+
module Silenceable
|
5
|
+
class << self
|
6
|
+
def apply(obj)
|
7
|
+
unless obj.respond_to?(:silenced?)
|
8
|
+
class << obj
|
9
|
+
include Silenceable
|
10
|
+
end
|
11
|
+
end
|
12
|
+
return obj
|
13
|
+
end
|
14
|
+
end
|
15
|
+
attr_accessor :silenced
|
16
|
+
@silenced = false
|
17
|
+
def silenced?; @silenced ? true : false; end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Livecode
|
2
|
+
|
3
|
+
# = Timer
|
4
|
+
#
|
5
|
+
# Timer lets you loop a block at a certain interval.
|
6
|
+
#
|
7
|
+
# timer = Timer.new(100) {puts "I'm executed every 100ms!"}
|
8
|
+
# timer.stop # Stops the execution
|
9
|
+
# timer.start # Starts the timer again
|
10
|
+
# timer.time = 200 # Reschedules the timer
|
11
|
+
#
|
12
|
+
# Proc objects are also supported:
|
13
|
+
#
|
14
|
+
# timer_proc = proc{puts "I'm a proc"}
|
15
|
+
# timer2 = Timer.new(100, timer_proc)
|
16
|
+
#
|
17
|
+
# Timer will try to compensate for the run time of your code in order to stay in sync.
|
18
|
+
|
19
|
+
class Timer
|
20
|
+
attr_accessor :time, :proc
|
21
|
+
|
22
|
+
def initialize(time, proc=nil, &block)
|
23
|
+
@time = time || 1
|
24
|
+
if proc
|
25
|
+
@proc = proc
|
26
|
+
elsif block_given?
|
27
|
+
@proc = block
|
28
|
+
end
|
29
|
+
@tread = nil
|
30
|
+
start
|
31
|
+
end
|
32
|
+
|
33
|
+
# Call the block
|
34
|
+
def call
|
35
|
+
Silenceable.apply(@proc) if @proc
|
36
|
+
if @proc && !@proc.silenced?
|
37
|
+
@proc.call
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Start the timer
|
42
|
+
def start
|
43
|
+
stop
|
44
|
+
timer = self
|
45
|
+
@thread = Thread.new do
|
46
|
+
next_time = Time.now
|
47
|
+
while true
|
48
|
+
timer.call
|
49
|
+
next_time += (timer.time.to_f / 1000)
|
50
|
+
sleep_time = next_time - Time.now
|
51
|
+
sleep(sleep_time) if sleep_time > 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
alias :run :start
|
56
|
+
|
57
|
+
# Stop the timer.
|
58
|
+
def stop
|
59
|
+
if @thread
|
60
|
+
@thread.exit
|
61
|
+
@thread = nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias :clear :stop
|
65
|
+
alias :end :stop
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/livecode.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{livecode}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Inge J\303\270rgensen"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-24}
|
13
13
|
s.default_executable = %q{livecode}
|
14
14
|
s.description = %q{A toolkit for livecoding using Ruby and TextMate on OSX}
|
15
15
|
s.email = %q{inge@elektronaut.no}
|
@@ -34,6 +34,16 @@ Gem::Specification.new do |s|
|
|
34
34
|
"extras/textmate/Ruby Livecode.tmbundle/Syntaxes/Ruby Livecode.tmLanguage",
|
35
35
|
"extras/textmate/Ruby Livecode.tmbundle/info.plist",
|
36
36
|
"lib/livecode.rb",
|
37
|
+
"lib/livecode/clock.rb",
|
38
|
+
"lib/livecode/clock_recipients.rb",
|
39
|
+
"lib/livecode/delay.rb",
|
40
|
+
"lib/livecode/extensions/main.rb",
|
41
|
+
"lib/livecode/extensions/numeric.rb",
|
42
|
+
"lib/livecode/extensions/object.rb",
|
43
|
+
"lib/livecode/extensions/string.rb",
|
44
|
+
"lib/livecode/loader.rb",
|
45
|
+
"lib/livecode/silenceable.rb",
|
46
|
+
"lib/livecode/timer.rb",
|
37
47
|
"lib/livecode_server.rb",
|
38
48
|
"lib/livecode_server/client.rb",
|
39
49
|
"lib/livecode_server/command.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: livecode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Inge J\xC3\xB8rgensen"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-24 00:00:00 +02:00
|
13
13
|
default_executable: livecode
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -47,6 +47,16 @@ files:
|
|
47
47
|
- extras/textmate/Ruby Livecode.tmbundle/Syntaxes/Ruby Livecode.tmLanguage
|
48
48
|
- extras/textmate/Ruby Livecode.tmbundle/info.plist
|
49
49
|
- lib/livecode.rb
|
50
|
+
- lib/livecode/clock.rb
|
51
|
+
- lib/livecode/clock_recipients.rb
|
52
|
+
- lib/livecode/delay.rb
|
53
|
+
- lib/livecode/extensions/main.rb
|
54
|
+
- lib/livecode/extensions/numeric.rb
|
55
|
+
- lib/livecode/extensions/object.rb
|
56
|
+
- lib/livecode/extensions/string.rb
|
57
|
+
- lib/livecode/loader.rb
|
58
|
+
- lib/livecode/silenceable.rb
|
59
|
+
- lib/livecode/timer.rb
|
50
60
|
- lib/livecode_server.rb
|
51
61
|
- lib/livecode_server/client.rb
|
52
62
|
- lib/livecode_server/command.rb
|