Sto lavorando su un framework di gioco e ho deciso di utilizzare OSGi per unire tutto insieme, poiché la modularità è fondamentale per il gioco stesso.
Voglio che il gioco sia eseguito come un pacchetto all-in-one sul computer di qualcuno, o che lo scriva come server, inserendo il server di login in un'istanza di Azure e avendo il motore di gioco in esecuzione su un'istanza AWS, oppure eseguendo il tutto da un Raspberry Pi.
Quando stavo lavorando su questo prima, ho diviso il lavoro in diversi servizi. Avevo un GameEngine
, un LoginServer
, un 2DGameClient
, ecc. Tuttavia, questi erano tutti cablati in un singolo barattolo, con una sola classe Main
, che assomigliava a qualcosa
public class Main {
public static void main(String[] args) {
final ExecutorService threadPool = Executors.newFixedThreadPool(3);
final Runnable gameEngine = new GameEngine();
final Runnable loginServer = new LoginServer();
final Runnable gameClient = new 2DGameClient();
threadPool.submit(gameEngine);
threadPool.submit(loginServer);
threadPool.submit(gameClient);
// ...
}
}
Dove ciascun servizio era il proprio thread all'interno di un pool di thread condiviso.
Tuttavia, ora che ho deciso di provare a progettarlo su OSGi da zero, mi chiedo come renderlo modulare come vorrei.
Quello che sto pensando finora è che, come minimo, avrò bisogno di 3 pacchetti per servizio, per esempio
- API del motore di gioco
- Provider di motori di gioco
- Attivatore del motore di gioco
Tuttavia, ritengo che la maggior parte del codice di attivatore sarebbe essenzialmente
public void start(BundleContext context) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
threadPool.submit(new Runnable() {
public void run() {
GameEngine engine = FindRegisteredGameEngine();
engine.start();
// ...
}
});
}
Ma poi non posso aspettare il risultato della chiamata submit
, perché secondo la documentazione start
dovrebbe tornare il prima possibile.
Sapendo che voglio che i servizi possano essere implementati come dove mai il più possibile, questi fornitori di servizi dovrebbero fornirsi come oggetti Runnable
? Se ci sono alcune condizioni preliminari che devono essere soddisfatte prima che un servizio possa essere eseguito (connessione al database, file di configurazione letti, ecc.) È allora la responsabilità del metodo run
? Esiste un modo giusto per farlo nel framework OSGi?