Ich habe etwas mit State-Management in Java herum experimentiert und mir etwas geschrieben, um den State von Web-Apps (Vue.js, React, AngularJS,..) auf einen Server auszulagern. So dass sich die States und Actions der verschiedenen Clients gegenseitig beeinflussen können (Datenaustausch), aber private Daten wie Tokens trotzdem für die einzelnen Clients isoliert bleiben. Neben den Reducern gibt es noch Facets für die Anpassung der Ausgabe (so etwas wie Getter in Vuex).
Ich wollte dann einmal das Grundsystem (State-Manager, Interfaces, Server + Controller) in einem Mave-Repository ablegen und die konkrete Implementierung der Reducer, Facets und Filter dann sauber getrennt in einem eigenen Projekt haben.
Das Repository sollte einfach bei Github liegen und nicht in eines der öffentlichen und großen mit rein genommen werden, da es ja erstmal ein Proof-Of-Concept für meine Idee zu verteilten Daten ist. Ich habe mich dabei an diesem DZone-Artikel orientiert.
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<!-- .... und noch mehr ..... -->
</dependencies>
</project>
Den Inhalt aus target/mvn-repo/hp-globalstate/hp-globalstate-core/ habe ich dann in ein Github-Projekt gepackt und hochgeladen. Das 2. Projekt kommt dann dieses dann hinzu:
public class Server {
public static void main(String[] args){
GlobalStateServer server = new GlobalStateServer();
List<Reducer> reducers = new ArrayList<>();
reducers.add(new de.hannespries.test.Reducer());
List<FacetFilter> facets = new ArrayList<>();
facets.add(new DefaultFacetFilterByToken(true));
Nach dem Ich mich etwas mit Redux beschäftigt habe, habe ich mir mal einen eher aktuellen Spiele-Prototypen von mir vorgenommen und geguckt, ob man diesen auf ein ähnliches Konzept umbauen kann. Also dass alles per Actions gesteuert wird. Alles was man macht wird per Action rein gereicht, in einer Loop(Interval) von einem Handler verarbeitet und dann gerendert, wenn mindestens eine Action ausgeführt wurde.
Nach einer schnellen Betrachtung wurde aber klar, dass ich da nicht viel umbauen konnte, weil die Engine schon rein der Logik wegen so implementiert wurde. Ich hab es einfach so schon gemacht ohne groß drüber nachzudenken. Ich hatte zusätzlich noch Action-Groups eingeführt, die dafür sorgen, dass immer nur die erste Action einer Gruppe ausgeführt wird (um Actors sich über die Map bewegen zu lassen, wobei alle Schritte vorberechnet sind und nicht vor dem Schritt dieser erst berechnet werden muss). Es gibt zwei Lanes: fast und slow. "slow" für das Bewegen von Actors auf der Map und "fast" für Eingaben und Dinge die an sich in Echtzeit da sein müssen. Ein kleine Verzögerung ist aber ok.
addIntervalEvent: function(eventType, eventArgs, group, lane){
this.interval.queue.push({lane: lane ? lane : 'slow',
type: eventType, args: eventArgs, parent: this.interval,
group: group});
},
performIntervallTick: function(lane){
//filter to perform events of a lane and remove this performed events
let filterCheck = [];
let render = false;
let newQueue = this.interval.queue.filter(item => {
let res = true;
if(item.lane == lane){
if(this.eventHandling[item.type] && (item.group === null || !filterCheck[item.group])){
this.eventHandling[item.type](item.args, item.parent, this);
filterCheck[item.group] = item.group;
res = false; //was performed and is removed from the queue
render = true;
}
}
return res;
});
this.interval.queue = newQueue;
//using the same method to trigger field-events
if(render){
this.globalKeyListener({keyCode: 0}, true);
this.renderViewport();
}
},
Hier bei ist der Controller der State und wird durch die Actions verändert. Eine Action wird mit einer Veränderung des State gleichgesetzt, da einmal oder zwei Rendern ohne das es nötig gewesen wäre in der Gesamtheit nichts ausmacht.
Was ich dabei gelernt habe ist, dass es schwer ist in JavaScript anders zu arbeiten, wenn man die Verarbeitung und die Ausgabe von einander entkoppelt, was gerade bei Anwendungen mit Grafik schwer ist nicht zu tun.
Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?