Scripting bearbetning med MIDI (4 / 11 steg)
Steg 5: Anpassad meddelande hanterare
Med hjälp av midiMessage är OK för enkla fall, såsom att ha skissen göra något oavsett vad not skickas eller kanske välja beteende baserat på två eller tre anteckningar, men om hitta koden fylla upp med långa if/then eller switch/fall uttalanden bör du vara försiktig. Dessa typer av strukturer kan bli svårt att upprätthålla.
Vad skulle vara renare än en växande uppsättning villkorssatser skulle vara ett sätt att anropa en metod baserad på notvärde. Här är ett sätt att göra det:
void midiMessage (MidiMessage meddelande, lång tidsstämpel, sträng bus_name) {
int Obs = (int)(message.getMessage() [1] & 0xFF);
int vel = (int)(message.getMessage() [2] & 0xFF);
println ("Bus" + bus_name + ": Obs" + OBS + ", vel" + vel);
invokeNoteHandler (Obs, vel);
}
void invokeNoteHandler (int note, int hastighet) {
försök {
Undergrupp [] cls = ny klass [1].
CLS [0] = int.class;
Metoden handler = this.getClass () .getMethod ("onNote" + note, cls);
handler.Invoke (här, hastighet);
} fånga (undantag e) {
e.printStackTrace();
}
}
När MIDI-meddelande drar midiMessage ut notvärde och hastighet. Det passerar dessa värden på invokeNoteHandler. Det är där roligt händer.
Java reflektion kan koden för att hitta metoder av namn (med getMethod) och kalla dem. Vi vill att en int värde till någon metod av formuläret onNote < SomeNoteValue >; för att hitta en metod som du behöver till både namnet och en uppsättning klasser som beskriver vilka argument att metoden tar.
När en referens till sådan metod finns det är anropade använder (överraskning!) åberopa.
Allt detta händer i ett try/catch block. Om något går fel (exempelvis den kod försöken hitta och en metod som inte finns) undantaget är mer eller mindre ignoreras. Tanken här är att vi kommer att ha metoder för vissa uppsättning anteckningar, och vi bryr oss inte om anteckningar för vilka det finns ingen motsvarande handler metod.
Den sista delen av detta är att definiera en eller flera metoder för att göra något för noteringar. Till exempel:
void onNote48 (int vel) {
om (vel > 0) {currentColor = vel * 2.}
}
void onNote50 (int vel) {
om (vel > 0) {currentColor = vel * 2.}
}
Inte fruktansvärt fantasifulla, men vad detta innebär är gränsen skärm-färg ändras till bara två anmärkningar.
Här är kanske ett bättre exempel:
Först ändra typ av currentColor:
färg currentColor = ny color(0,0,0);
Nu har Obs hanterarna ange olika färger:
void onNote48 (int vel) {
om (vel > 0) {currentColor = färg (255, vel * 2, vel * 2);}
}
void onNote50 (int vel) {
om (vel > 0) {currentColor = färg (vel * 2, 255, vel * 2);}
}
void onNote52 (int vel) {
om (vel > 0) {currentColor = färg (vel * 2, vel * 2, 255);}
}
Det viktiga är att beteendet för någon viss anmärkning är inkapslat i sin egen metod i stället för att vara förlagda i en växande allomfattande metod.
Vi kan göra saker renare ändå genom att sätta alla metoderna som Obs-hantering i en separat fil (t.ex. noteHandlers.pde) så du vet exakt var du ska leta för att lägga till eller ändra på någonting.
Egna meddelande hanterare kan vara vad du vill, och kan du passera i andra parametrar, kanske passera i själva ursprungliga MIDI-meddelandet. Men du ställa in det upp du behöver ställa in din version av invokeNoteHandler så att det söker efter metoder med den korrekta parametersignaturen.
Till exempel om du vill använda handler metoder som tar Obs hastigheten och buss namnet, behöva du ändra arrayen klass som används med getMethod för att ange vilka typer av dessa två parameter:
void invokeNoteHandler (int anteckning, int hastighet, sträng busName) {
försök {
En matris med storlek 2 eftersom vi letar efter en metod som
tar två argument
Undergrupp [] cls = ny klass [2].
CLS [0] = int.class;
CLS [1] = String.class;
Metoden handler = this.getClass () .getMethod ("onNote" + note, cls);
Nu kalla metoden ligger med två argument
handler.Invoke (här, hastighet, busName);
} fånga (undantag e) {
e.printStackTrace();
}
}