280 lines
14 KiB
Java
280 lines
14 KiB
Java
package Jcd; // -- Listing-5 -- SmartDrive.java 1
|
|
// 2
|
|
import java.io.*; // 3
|
|
import java.util.*; // 4
|
|
import java.awt.*; // 5
|
|
import Jcd.Drive; // 6
|
|
import Jcd.Monitor; // 7
|
|
// 8
|
|
class SmartDrive
|
|
extends Drive implements Observer { // 9
|
|
// 10
|
|
public Monitor monitor; // 11
|
|
public TrackList tracksToPlay = null; // 12
|
|
public int program_pos = 0; // 13
|
|
public boolean singleMode = false; // 14
|
|
// 15
|
|
public SmartDrive(String device, // 16
|
|
String module, int flags)
|
|
{ // 17
|
|
super(device, module, flags); // 18
|
|
setUp(); // 19
|
|
} // 20
|
|
// 21
|
|
protected void setUp() // 22
|
|
{ // 23
|
|
monitor = new Monitor(this); // 24
|
|
monitor.addObserver(this); // 25
|
|
tracksToPlay = new TrackList(30); // 26
|
|
} // 27
|
|
// 28
|
|
public void setSingleMode(boolean state) // 29
|
|
{ // 30
|
|
singleMode = state; // 31
|
|
} // 32
|
|
// 33
|
|
public void play(int track) // 34
|
|
throws DriveException
|
|
{ // 35
|
|
if (singleMode) single(track); // 36
|
|
else super.play(track); // 37
|
|
} // 38
|
|
// 39
|
|
public boolean startPlaying() // 40
|
|
throws DriveException
|
|
{ // 41
|
|
if (status() == Drive.STATUS_PAUSED) // 42
|
|
resume(); // 43
|
|
else if (!tracksToPlay.isEmpty()) { // 44
|
|
if (tracksToPlay.atEnd()) // 45
|
|
tracksToPlay.reset(); // 46
|
|
play(tracksToPlay.nextTrack()); // 47
|
|
} // 48
|
|
else play(1); // 49
|
|
return true; // 50
|
|
} // 51
|
|
// 52
|
|
public boolean next() throws DriveException// 53
|
|
{ // 54
|
|
if (tracksToPlay.isEmpty()) { // 55
|
|
int track = currentTrack(); // 56
|
|
int max = numberOfTracks(); // 57
|
|
if (track >= max) return false; // 58
|
|
play(track + 1); // 59
|
|
} // 60
|
|
else { // 61
|
|
int next = tracksToPlay.nextTrack(); // 62
|
|
if (next <= 0) // 63
|
|
return false; // 64
|
|
play(next); // 65
|
|
} // 66
|
|
return true; // 67
|
|
} // 68
|
|
// 69
|
|
public boolean prev() throws DriveException// 70
|
|
{ // 71
|
|
if (tracksToPlay.isEmpty()) { // 72
|
|
int track = currentTrack(); // 73
|
|
if (track <= 1) return false; // 74
|
|
play(track - 1); // 75
|
|
} // 76
|
|
else { // 77
|
|
int next = tracksToPlay.prevTrack(); // 78
|
|
if (next <= 0) return false; // 79
|
|
play(next); // 80
|
|
} // 81
|
|
return true; // 82
|
|
} // 83
|
|
// 84
|
|
public int remaining() // 85
|
|
{ // 86
|
|
int result = 0; // 87
|
|
if (tracksToPlay.isEmpty()) // 88
|
|
result = monitor.cdEndAddress -
|
|
monitor.currentAddress; // 89
|
|
else { // 90
|
|
int index = 0; // 91
|
|
Enumeration iter = tracksToPlay.elements();
|
|
while (iter.hasMoreElements()) { // 93
|
|
int track = // 94
|
|
((Integer) iter.nextElement()).intValue();
|
|
if (index >= tracksToPlay.stepNumber() &&
|
|
track < monitor.trackLength.length) {
|
|
result += monitor.trackLength[track];
|
|
} // 98
|
|
index++; // 99
|
|
} // 100
|
|
if (!tracksToPlay.atStart() &&
|
|
!tracksToPlay.atEnd()) { // 101
|
|
result -= (monitor.currentAddress - // 102
|
|
monitor.trackStartAddress);
|
|
} // 103
|
|
} // 104
|
|
return result; // 105
|
|
} // 106
|
|
// 107
|
|
public int togglePause() // 108
|
|
throws DriveException
|
|
{ // 109
|
|
if (status() == Drive.STATUS_PAUSED) { // 110
|
|
resume(); // 111
|
|
return Drive.STATUS_PLAY; // 112
|
|
} // 113
|
|
pause(); // 114
|
|
return Drive.STATUS_PAUSED; // 115
|
|
} // 116
|
|
// 117
|
|
public synchronized void update(Observable o,
|
|
Object arg)// 118
|
|
{ // 119
|
|
try { // 120
|
|
if (monitor.status != Drive.STATUS_INVALID) {
|
|
if (monitor.cdChanged) // 122
|
|
tracksToPlay.clear(); // 123
|
|
else if (monitor.status ==
|
|
Drive.STATUS_PLAY) { // 124
|
|
int track= monitor.currentTrack; // 125
|
|
int tend= monitor.trackEndAddress[track];
|
|
if (monitor.currentAddress >=
|
|
tend - 210) { // Near end of track?
|
|
// Poll frequently so we don't miss the
|
|
// event. // 128
|
|
while (currentAddress() < tend &&// 129
|
|
monitor.status == Drive.STATUS_PLAY
|
|
&& currentAddress() != 0) { // 131
|
|
try { Thread.sleep(100); // 100 msec
|
|
} // 133
|
|
catch (InterruptedException e) {
|
|
} // 135
|
|
} // 136
|
|
if (!tracksToPlay.atStart()) // 137
|
|
programEndOfTrack(); // 138
|
|
else // Normal play // 139
|
|
normalEndOfTrack(track); // 140
|
|
} // 141
|
|
} // 142
|
|
} // 143
|
|
} // 144
|
|
catch (DriveException e) { // 145
|
|
System.out.println("Exception: " + e); // 146
|
|
} // 147
|
|
} // 148
|
|
// 149
|
|
protected void programEndOfTrack() // 150
|
|
{ // 151
|
|
try { // 152
|
|
int next = tracksToPlay.nextTrack(); // 153
|
|
if (tracksToPlay.atEnd()) { // 154
|
|
stop(); tracksToPlay.reset();
|
|
}
|
|
else if (singleMode) stop(); // 155
|
|
else play(next); // 156
|
|
} // 157
|
|
catch (DriveException e) { // 158
|
|
System.out.println( // 159
|
|
"Program end of track exception: " + e);
|
|
} // 160
|
|
} // 161
|
|
// 162
|
|
protected void normalEndOfTrack(int track) // 163
|
|
{ // If during the track we switched play // 164
|
|
// modes, ensure the correct behaviour occurs.
|
|
try { // 165
|
|
if (singleMode) stop(); // 166
|
|
else if (track < monitor.numberOfTracks)
|
|
play(track + 1); // 167
|
|
} // 168
|
|
catch (DriveException e) { // 169
|
|
System.out.println(
|
|
"Normal-Play end of track exception: " + e);
|
|
} // 171
|
|
} // 172
|
|
} // 173
|
|
// 174
|
|
class TrackList extends Vector { // 175
|
|
|
|
// Gone past last track. // 176
|
|
protected boolean at_end = false;
|
|
protected Integer current = null; // 177
|
|
// 178
|
|
TrackList(int initial_n) { // 179
|
|
super(initial_n);
|
|
}
|
|
public synchronized void addTrack(int t) { // 181
|
|
addElement(new Integer(t));
|
|
}
|
|
// 182
|
|
public synchronized void removeTrack(int t)// 183
|
|
{ // 184
|
|
for (int pos = size() - 1; pos >= 0; pos--) {
|
|
Integer elem = (Integer) (elementAt(pos));
|
|
if (elem.intValue() == t) { // Found // 187
|
|
removeElement(elem); // 188
|
|
if (elem==current) // Select a new current
|
|
current = (Integer) ((pos>=size()) ?
|
|
lastElement() : elementAt(pos)); // 190
|
|
} // 191
|
|
} // 192
|
|
} // 193
|
|
// 194
|
|
public synchronized int stepNumber() // 195
|
|
{ // Program step number // 196
|
|
return (current != null) ?
|
|
indexOf((Object) current) : 0 ; // 197
|
|
} // 198
|
|
// 199
|
|
public synchronized int currentTrack() // 200
|
|
{ // 201
|
|
return
|
|
(current != null) ? current.intValue() : 0 ;
|
|
} // 203
|
|
// 204
|
|
public synchronized int nextTrack() // 205
|
|
{ // Advance along the list by one. // 206
|
|
if (size() == 0) return 0; // 207
|
|
if (current == null) // 208
|
|
current = (Integer) firstElement(); // 209
|
|
else { // 210
|
|
int pos= indexOf((Object) current) + 1;// 211
|
|
at_end= pos == size(); //Finished last track?
|
|
current = (Integer) (at_end ?
|
|
lastElement() : elementAt(pos)); // 213
|
|
} // 214
|
|
return current.intValue(); // 215
|
|
} // 216
|
|
// 217
|
|
public synchronized int prevTrack() // 218
|
|
{ // 219
|
|
if (current != null) { // 220
|
|
int pos= indexOf((Object) current) - 1;// 221
|
|
current = (Integer) ((pos<0) ?
|
|
firstElement() : elementAt(pos)); // 222
|
|
return current.intValue(); // 223
|
|
} // 224
|
|
return 0; // 225
|
|
} // 226
|
|
// 227
|
|
public boolean atStart() // 228
|
|
{ return current == null ; }
|
|
public boolean atEnd() { return at_end; } // 229
|
|
// 230
|
|
public void skipTo(int track) // 231
|
|
{ // 232
|
|
if (size() > 0) { // 233
|
|
while (!atEnd()) // 234
|
|
if (nextTrack() == track && !atEnd())
|
|
return;
|
|
reset(); // Wrap around to the start // 235
|
|
while (!atEnd()) // 236
|
|
if (nextTrack() == track)
|
|
return;
|
|
current = (Integer) lastElement(); // 237
|
|
} // 238
|
|
} // 239
|
|
// 240
|
|
public synchronized void clear() // 241
|
|
{ reset(); removeAllElements(); }
|
|
public synchronized void reset() // 242
|
|
{ current = null; at_end = false; }
|
|
} // 243
|