Blog: Latest Entries (15):


JavaScript: FlushQueue Konzept

Eine Art von Queue, wo viele Items drin abgelegt werden können, aber erst wenn alle Items valide sind, alle auf einmal verarbeitet werden. Es werden Proxies benutzt, um auf Änderungen an den Items reagieren zu können. Ein hinzu gefügtes Item kann also an eine async Function weiter gereicht werden und wenn dort das Item geändert wird, wird direkt wieder versucht die Queue zu flushen.

Man muss drei Functions mit geben: Validator zum prüfen der einzelnen Items, Cosumer zum Verarbeiten der einzelnen Items und onEmpty, die ausgeführt wird, wenn der Flush durch ist.


let flushQueue = {
items: [],
getChangeHandler: function(service){
return {
set: (obj, prop, newval) => {
obj[prop] = newval;
service.consume(false);
}
}
},
consumer: null, //user function
onEmpty: null, //user function
validator: null, //user function
validate: function() {
let result = true;
this.items.forEach((item) => {
if(!this.validator(item)) {
console.log(item);
result = false;
}
});
return result && this.items.length > 0;
},
consume: function(tested) {
if(tested || this.validate()) {
var item = this.items.shift();
if(this.consumer){
try{
this.consumer(item);
}
catch(e){
}
}

if(this.items.length > 0) {
this.consume(true);
}
else if(item && this.onEmpty) {
this.onEmpty();
}
}
},
add: function(itemIn) {
let item = new Proxy(itemIn, this.getChangeHandler(this));
this.items.push(item);
this.consume(false);
return item;
},
addAll: function(items) {
let out = [];
items.forEach((itemIn, key) => {
let item = new Proxy(itemIn, this.getChangeHandler(this));
this.items.push(item);
out[key] = item;
});
this.consume(false);
return out;
}
};


Beispiel:

flushQueue.validator = (item) => {
return item.checked;
};
flushQueue.onEmpty = () => {
console.log("flushed!");
};
flushQueue.consumer = (item) => {
console.log("consumed -> " + item.id);
return true;
}

let items = [
{id: 1, checked: true},
{id: 2, checked: true},
{id: 3, checked: true},
{id: 4, checked: true},
{id: 5, checked: true},
{id: 6, checked: true},
{id: 7, checked: false},
];

let itemsP = flushQueue.addAll(items);
console.log("add all");
console.log("pre change");
itemsP[6].checked = true;
console.log("post change");


bbcode-image


Man muss noch viel verbessern wie eine Fehlerbehandlung beim Verarbeiten von Items.

Schreib dich nicht ab.. lern Textnachrichten

In letzter Zeit nehmen leider schlimme Dinge wie Sprachnachrichten und Videoanrufe über Whatsapp zu. Auch Menschen von denen man weiß, dass sie eigentlich lesen und schreiben können, scheinen eben dieses zu verlernen... Ähmm ja.. Eigentlich geht es mir darum, dass diese Art von Nachrichten für mich fast immer sehr unpraktisch und eher nervig sind als einen Mehrwert darzustellen. Deswegen hier einmal kurz, warum ich Textnachrichten vorziehe:

Sprachnachrichten sind unpraktisch, weil...
- sie mehr vom Datenvolumen verbrauchen als Textnachrichten und das ist in Deutschland immer sehr begrenzt oder sehr teuer
- sie die Umgebung belästigen, weil ich sie mir laut anhören muss und vielleicht nicht möchte, dass alle in der Umgebung mithören oder sich da druch gestört fühlen
- sie sind teilweise schlecht zu verstehen, also müsste ich sie lauter machen (siehe Punkt 2) oder muss mit Stellen 2 mal anhören, was mit der kleinen Timeline und Touchbedienung, gar nicht so einfach ist, die richtige Stelle mehr mal zu treffen
- sie bei schlechten Netz teilweise nicht übertragen werden können

Sprachnachrichten sind ok, wenn...
- ich wirklich eine Audioaufnahme von etwas teilen möchte
- wenn ich Auto fahre, aber dann geht auch Sprachsteuerung und vorlesen lassen

Videoanrufe sind unpraktisch, weil...
- sie sofort angenommen werden müssen und ich meistens (gerade bei der Arbeit) keine Zeit dafür habe
- ich sie nicht später beantworten kann (bei Sprachnachrichten geht das ja noch)
- ich nicht voll multitasking mässig mit mehreren gleichzeitig kommunizieren kann

Videoanrufe sind ok, wenn...
- wenn ich zum Beispiel bei handwerklichen Dingen Echtzeit-Hilfe brauche und die andere Person es sehen muss während ich etwas mache
- ...für private Dinge...
- Für alte Leute, weil es wie Telefonieren ist und ältere Menschen mit asynchroner Kommunikation überfordert sind.. sie wollen immer sofort antworten und auch sofort Reaktionen haben bei der Kommunikation

HD+ ist wieder da

Mal wieder kam eine Bestellbestätigung von HD+ an. Selbes Schema, wie das letzte mal. Wirklich toll ist, dass die letzten Male sogar eine Email mit dem SEPA-Mandat mitgeschickt wurde, weil damit lässt sich sehr genau sagen, welche Daten von einem von jemanden Missbraucht werden und welche nicht. Daher kann ich jetzt schon mal sagen, dass jemand wohl regelmäßig meine Email-Adresse für Bestellungen verwendet, aber immer mit anderen Bankdaten kombiniert. Das ist an sich nicht sehr klug von dieser Person, da so Unregelmäßigkeiten schnell zu finden sein sollten. Eine Email-Adresse mit verschiedenen Kontodaten sollte sich per SQL schnell finden lassen.

Diesmal habe ich eine Email geschrieben und auch, um die Rücknahme der Bestellung gebeten. Mal gucken wie die reagieren werden.

Die Kontodaten stammen diesmal von der VR GenoBank DonauWald eG... also irgendwo aus Bayern.

Edit:
HD+ hat mir geraten bei der Polizei Anzeige gegen Unbekannt zu erstatten.

Gedanken zum agilen Arbeiten

Agil arbeiten ist voll in und jeder will es machen. Klingt eben cool, wenn man sagen kann, dass man Scrum macht und UserStories entwirft und danach arbeitet. Leider ist agiles Arbeiten nichts, was man den Mitarbeitern einfach mal vorschreiben kann und es dann auch so in Zukunft läuft. Agil ist viel mehr als ein Whiteboard mit ToDos und Sprints mit 2 Wochen Laufzeit, wo am Ende es Sprints alles fertig ist, was man an das Board geklebt hat.

Wenn man wirklich agil arbeiten will, muss man erst einmal sich um die Hierarchie kümmern, weil diese agilen Arbeiten meistens im Weg steht. Wer so arbeitet, dass Aufgaben durch 3-4 Schichten von Oben nach Unten herunter gereicht werden und jeder nur die Infos bekommt, die er gerade braucht, wird das ganze Vorhaben scheitern. Wichtig beim agilen Arbeiten ist, dass die Mitarbeiter, die es umsetzen sollen, auch vollumfänglich informiert sind und nicht nur das wissen, was in dem aktuellen Sprint umgesetzt werden sollen.

Oft läuft es so das der Chef seine Idee mit dem Abteilungsleiter bespricht, der guckt was zu machen ist und stimmt sich mit dem Teamleiter/Scrummaster ab was in einem Sprint abgearbeitet werden soll. Die Mitarbeiter dürfen dann noch mal die Aufwände schätzen für das was sie in der Zeit erledigen sollen. Meistens müssen, dann die Aufwände aber dann auch so geschätzt werden, dass es passt, weil der Inhalt des Sprints ja schon fest gelegt wird. Was im Backlog für die nächsten Sprints steht, wird oft nicht mitgeteilt. Damit wird den Mitarbeitern aber die Möglichkeit genommen schon mal Erkenntnisse und konkretes Wissen für die Zukunft zu sammeln. Weil.. man ist ja agil und wenn sich die Arbeit des Sprints leider als nicht zukunftssicher heraus stellt, macht man es eben nochmal. Aber Hauptsache man wird am Sprintende mit den Aufgaben fertig.

Im Grunde kennt man dieses Vorgehen schon lange. Man bekommt die Anforderungen diktiert, dann werden diese umgesetzt und am Ende wird geguckt, ob es das ist was man haben wollte. Wenn nicht fängt man wieder von vorne an. Das ist das klassische Wasserfall-Model.
Nur eben auf 2 Wochen herunter gebrochen. Das ist nicht Agil. Man blickt nicht über den Tellerrand und passt sich ändernden Anforderungen an. Wenn sich mitten drin was ändert wird es oft nicht mitgeteilt, wenn dann heißt es man müsse das Sprintziel um jeden Preis erreichen und im nächsten Sprint würde man es eben dann nochmal machen.

Planung und Konzeption wird weiterhin von der "Führungsebene" gemacht. Die Mitarbeiter arbeiten nur wieder stur nach Vorgaben ihre ToDos ab. Sollte ein ToDo in der Umsetzung nicht genau spezifiziert sein, kann dieses nicht bearbeitet werden. Ein Konzept kann sich nicht mit der Zeit entwickeln, weil es kein Feedback über Erkenntnisse und neue Erfahrungen gibt.
Hier ist aber nicht nur die "Führungsebene" schuld, sondern oft auch Mitarbeiter, die viel lieber nach festen Vorgaben arbeiten und nicht selbst die Lösung für das Problem entwickeln wollen. Die Verantwortung für ein Produkt wird da immer noch nach oben gereicht, weil der Mitarbeiter führt ja nur aus.

Wie macht man es besser. Man braucht eine direkte und vollständige Kommunikation über alle Grenzen hinweg. Die Vision muss allen klar sein und jeder muss auch bereit sein diese selbstverantwortlich um zu setzen. Jeder soll eine Lösung vorschlagen können. Bei klaren Anforderungen muss auch nicht jeder Pups besprochen werden, weil jeder ja daran interessiert ist, das Produkt fertig zu stellen, wird auch jeder die seiner Ansicht nach beste Lösung implementieren. Und wenn man ehrlich ist, kann jede andere Lösung genau so "richtig" oder "falsch" sein, wie die andere. Zu viel diskutieren bringt am Ende nichts, lieber machen und ausprobieren.
Niemand wird dir das Denken dabei abnehmen. Immer mit denken und den Denkprozess und die Entscheidungen dazu immer dicht man Entwicklungsprozess halten. Bei den Meetings können Vorschläge gemacht werden, aber diese sind nicht in Stein gemeißelt sondern wie gesagt nur Vorschläge und mögliche Lösungen. Wenn es sich auf halben Wege heraus stellt, dass es nicht so geht.. abbrechen und direkt neu anfangen. Ein Sprintziel ist nie wichtiger als das Produkt. Was bringt es ein Feature zu Ende zu implementieren, wenn die Implementierung sowie so
wieder verworfen wird? Nichts.. es verbraucht nur Zeit und Kunden könnten glauben, es würde doch schon fertig sein. Wenn man etwas macht, dann richtig und dafür darf man keine Angst haben mal was aus zu probieren und dann mit dem Versuch auch zu scheitern.

Retrospektiven und Meetings sind wichtig, weil da keine nach unten gerichtete Kommunikation stattfindet, sondern alle auf Augenhöhe mit einander reden können. Auf von "unten" muss klar kommuniziert werden, was und wie viel man schafft und schaffen will. Ein Sprint ist kein Zeitraum wo man möglichst viele Aufgaben reindrückt und am Ende Crunchtime erzeugt, damit das Sprintziel auf jeden Fall erreicht wird. Lieber weniger einplanen und dem Sprintende entspannt und zufrieden entgegen sehen. Lieber die Zeit nutzen um Lösungen zu entwickeln und geplante ToDos noch mals zu analysieren und schon mal etwas auszuarbeiten.

Viele leben aber noch zu sehr in ihrer hierarchischen Wasserfall-Welt, wo Kommunikation nur in eine Richtung geht, nur konkrete Ausgaben kommuniziert werden und ein Sprint ein Timeslot ist, in dem man möglichst viel Arbeit erledigt haben will und das Sprintende eher drohend sein soll und nicht erwartet werden soll.

Agil bedeutet für mich, dass Informationen in alle Richtungen fließen und einen beim Denken und Lösungen finden immer zur Verfügung stehen. Agil ist, wenn man schnell austestet, schnell scheitert und schnell mit der mehr Erfahrung von neuen beginnen kann. Wo man neue Fehler machen kann um so zu neuen Lösungen zu kommen. Und für all dieses übernehme ich dann auch gerne die Verantwortung

Shopware: Traue keinem Subscriber!

Subscriber bei Shopware-Plugins sind immer so ein Problem. Sie nehmen Daten manipulieren diese und reichen sie an den nächsten Subscriber weiter. Wenn ein Subscriber in einen Fehler läuft und z.B. leere Daten in die Arguments zurück schreibt, ist am Ende alles kaputt und die Daten sind verloren gegangen. Das ist mir jetzt einmal passiert und deswegen, bin ich darauf umgeschrieben, dass Subscriber nur noch auf einer Kopie arbeiten
dürfen.


$outputModelCopy = new \ArrayObject($outputModel);
$outputModelCopy = $this->fireEvent('decorate_model', $outputModelCopy);
if($outputModelCopy && count($outputModelCopy->getArrayCopy()) > 0){
$outputModel = $outputModelCopy->getArrayCopy();
}


Sollte nun etwas schief gehen und die Daten verloren gehen, werden einfach die Ursprungsdaten weiter verwendet. Wenn nun zusätzliche Daten nicht dazu dekoriert werden, ist es zwar doof und man muss in das Log-File gucken, ob Fehler auftraten, aber der Ablauf funktioniert weiter und es kommen immer hin die Grunddaten weiter dort an wo sie hin sollen.

Gerade bei Exports oder Imports mit kritischen und unkritischen Daten zusammen, ist es immer besser wenigstens die kritischen Daten sicher zu haben als gar nichts zu haben. Unkritische Daten kann man meistens dann sogar per Hand nachpflegen.

Identitätsdiebstahl und Koblenz

HD+ Kunden, die sich ein neues Programmpaket bestellen, gehen oft nach einem bestimmten Muster vor. Sie geben eine beliebige Email-Adresse (bestimmt geht auch eine nicht existente und rein ausgedachte Email-Adresse) und dann geben sie eine beliebige Bankverbindung ein. Mehr Daten braucht man da wohl auch nicht. Dann bekommt vielleicht jemand eine Rechnung (in diesem Fall ich) und irgendwer muss bezahlen (in diesem Fall jemand auf Koblenz).

Wenn man sich als Rechnungsempfänger da meldet, interessiert es da keinen, weil ja hoffentlich der 2. dumme es nicht merkt und die Rechnung bezahlt.

Da ich schon mehrmals mit genau dem selben Vorgang bei HD+ als Rechnungsempfänger zu tun hatte, scheint es da wirklich System zu haben. Leider gibt HD+ an der Hotline auch direkt an, daran nichts ändern zu wollen.

Ich bin gespannt, wann die nächste Email bei mir aufläuft.

bbcode-image

Java: Eine Fat Jar mit allen Dependencies

Manchmal ist es echt unpraktisch viele kleine JAR-Dateien zu haben und man hätte gerne alles in einer großen. Keine Class-Path Probleme mehr, einfaches Deployen und ein Single-Point-Of-Failure.

Mit Maven geht das zum Glück sehr einfach. Spring Boot und Meecrowave haben eigene Plugins mit denen man auch sehr gut arbeiten kann und die dem Beispiel hier vorzuziehen sind.


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>de.hannespries.time.gui.MainFrame</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>


bbcode-image


Shopware: XML-Export + SCP

Die Windeit-Software GmbH wird in der nächsten Zeit eine neue Version des Automatic XML-Export Shopware-Plugins veröffentlichen. Es hat nun die Version 2.0.0 erreicht und kann jetzt selbstständig per SCP XML-Dateien auf einen anderen Server laden.

Dafür muss die php-ssh2 Extension installiert sein, was unter Ubuntu sehr einfach geht:

sudo apt-get install php7.2-ssh2


Auf dem Ziel Server muss der Openssh-Server installiert sein.

bbcode-image


Danach müssen nur noch die Verbindungsdaten eingegeben werden und der SCP-Upload aktiviert werden.

bbcode-image

Mein erstes Unix: Bull DPX/2

Mein erster Unix Rechner war ein Bull DPX/2 mit Motorolla 68030 CPU, 4MB RAM und einem Unix-Derivat. Vorher genutzt von dem DRK und man musste sich mit einem Serial VT-100 kompatiblen Terminal verbinden. Zum "Glück" war das UUCP-Konto nicht geschützt und so war es möglich sich das erste mal in VI zu verirren und erste Erfahrungen mit Unix zu machen.

bbcode-image


Der Rechner war riesig und schwer (eingebaute USV am Boden des Gehäuses), aber alles war von der Rückseite aus entfernbar und man konnte viel über die Computer-Architektur der 80er Jahre lernen.

Und wegen dem AM27C1024 EPROM: 50 Jahre AMD!

Firma mit familiären Klima

Man stolpert doch immer mal wieder über Firmen, die in Stellenanzeigen mit familiären Klima werben. Das ist so ein Überbleibsel der 70er und 80er Jahre wo Familie einen sehr hohen Stellenwert zugewiesen wurde. Gefühlt auch damals schon nicht immer zu Recht... aber zurück zu den Firmen. Familie an sich ist erst einmal super. Man hat Vertraute und bekommt Hilfe, wenn man sie braucht. Aber auch dort gibt es Diskussionen und Streit. Wenn man sich jetzt einmal vorstellt man würde in einer Firma arbeiten, die nur mit Familienmitgliedern besetzt ist und man ist nicht Chef. Wenn es in dieser Firma zu einer großen Diskussion kommen würde, könnte jeder bestimmt schnell ein Familienmitglied benennen, das schon nach kurzer Zeit beleidigt sich aus der Diskussion ausklinken würde, weil es nicht nach dieser Person geht.
Familie hat eben den einen Nachteil, dass dort alles auf persönlicher Ebene geregelt wird und nicht auf professioneller. Eben auch Konflikte und Meinungsverschiedenheiten. Wenn nun in einer Firma diskutiert wird und man kommt nicht auf einen Nenner, wird der Chef/Teamleiter irgendwann das abbrechen und sich für eine Ansicht entscheiden mit der man dann eben weiter arbeiten wird. Niemand würde ihm das übel nehmen, weil es eben sein Job ist und man ja auch irgendwie weiter machen muss. Wenn jemand damit nicht zurecht kommt, dass es nicht nach ihm geht, ist die Person leider in der Abteilung/Firma falsch.

In einer Firma mit familiären Klima ist alles persönlich und wird nur auf einem persönlichen Niveau ausgetragen. Ein großes Problem ergibt sich aber daraus, dass es so auch erwartet wird und auch klar nach dem Motto gelebt wird, man könne sich seine Familie ja nicht aussuchen. Dadurch kommt es, dass der Chef sich mit bestimmten Mitarbeiten nur streitet, beide beleidigt sind und es in großen Konflikten ausufert (auch mal mit Geschrei oder das einer mucksch vor dem PC sitzt und den anderen demonstrativ ignoriert*). Aber der Chef würde diese Person nicht feuern, weil es wie in einer Familie ist, wo man zwar mit einigen verwandt ist, aber wegen einem Streit seit Jahren nicht mehr gesprochen hat.
Das Kündigen wird, dann auch als Verrat an der Familie/Firma aufgefasst, egal wie schlecht es vorher lief.

So kann aber eine Firma und Team nicht funktionieren. Auch Menschen, die sich nicht mögen, können auf professioneller Ebene zusammen arbeiten. Sollte es einfach nicht gehen, muss man dann eben getrennte Wege gehen und einer muss das Team verlassen/wechseln.

Ich würde nicht in einer Firma anfangen, die sich wie eine Familie fühlt. Firmen sollen Firmen sein und Familien bleiben Familien. Keines von beiden ist perfekt, aber wenn man es mischt, kommt es meistens dazu, dass nur die schlechten Teile von beiden zusammen kommen und nicht die guten.

Der englische Begriff für das was ich meine ist Psychological safety. Wo man weiß, dass die eigene Meinung auf professioneller Ebene beurteilt, wird und nicht auf persönlicher.

* das habe ich sogar einmal persönlich erlebt

Node.js und Elasticsearch

Ein paar kleine Code-Snippets, um grundlegende Funktionen in node.js mit Elasticsearch implementieren zu können.

Elasticsearch-Client installieren:

npm install elasticsearch get-json


Client erstellen:

var elasticsearch = require('elasticsearch');

var client = new elasticsearch.Client( {
hosts: [
'http://localhost:9200/'
]
});


Index erstellen:

if(!client.indices.exists("testidx")){
client.indices.create({
index: "testidx"
}, (error, resp, status) => {console.log(status)}
);
}


Document speichern:

client.index(
{
index: "testidx",
type: "item",
id: "1",
body: {
id: "123",
value: "blubb"
}
}
);


Ein einfaches Query mit Callback-Function:

client.search({
index: 'testidx',
type: 'item',
body: {
query: {
match: { "id": "123" }
},
}
}, (error, response,status) => {
console.log("-- Hits --");
response.hits.hits.forEach((hit) => {
console.log(hit);
});
});


Ein einfaches Query mit Promise:

client.search({
index: 'testidx',
type: 'item',
body: {
query: {
match: { "id": "123" }
},
}
}).then((response) => {
response.hits.hits.forEach((hit) => {
console.log(hit);
});
}, (error) => {console.log(error);})


Mit Hilfe dieser Seite https://www.compose.com/articles/getting-started-with-elasticsearch-and-node/ zusammen gebastelt und hiermit https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/quick-start.html ergänzt.

Blackmagic DaVinci Resolve: Video Speedup

Im Gegensatz zu NCH Videopad, das nur bis 800% Speedup kommt (man muss für mehr zwischen durch immer exportieren), kann Blackmagic DaVinci Resolve auch weit über 1000% beschleunigen, so dass man man 11:00min auf unter 1min stauchen kann. Das geht auch ganz einfach. Auf den Clip den man ändern möchte mit einem Rechtsklick das Context-Menü öffnen und "Change Clip Speed" auswählen. Wenn man die %-Zahl ändert, sieht man auch direkt welche Länge der Clip dann haben wird.

bbcode-image


In der Vorschau ruckelte es zwar noch sehr, aber nach dem Exportieren lief alles es flüssig. Ich muss mich wohl noch mal mit den Vorschau-Einstellungen auseinander setzen. Da es nur ein 720p Video war und nicht mal 4K.

Kostenlose Multimedia Programme

ESM-Computer hat einen sehr interessanten Blog-Post geschrieben, der mich an alte Zeiten in Foren erinnert hat, wo man Freeware und Open-Source Listen hatte, damit die Mitglieder nicht ihr Geld für "fragwürdige" Software ausgeben, ob man für weniger (also nichts) mehr bekommen würde und auch um etwas zu Zeigen, dass es neben Adobe noch andere Lösungen gibt. Meiner Meinung nach fehlen in dem ESM-Post aber noch ein paar sehr gute Lösungen.

1. Videoplayer
Da hat ESM-Recht... ich hatte den noch auf NT 4.0 laufen und es gab damals eigentlich keine Alternative. Es gibt den Server nicht mehr.. ja.. es gab einen Server und einen Client (das C in VLC steht für Client).
Man kann Video-Streams nehmen und ein eigenes Logo einbauen und es dann weiter streamen. Auch auf kleiner Hardware mit 1,2GHz und 2GB kann man ohne Probleme einen Stream von einem SAT-IP Server streamen und so ein Stream braucht wirklich Bandbreite.. wirklich viel.

2. Audio
Seit neusten gibt es Cakewalk Sonar als Freeware. Seit Cakewalk-Zeiten (Cakewalk 5.0?) war es immer eine gute Lösung, auch wenn der aktuellen Freeware-Version einiges fehlen soll, ist es sicher immer noch eine gute Lösung.

3. Video
Ich habe Lightworks ausprobiert und fand es so gut wie unbedienbar. Gerade für kleine Video hatte ich nicht die Ruhe mich lange damit zu beschäftigen. Früher war Adobe mit Premiere und AfterFX das Non+Ultra. Es gab noch exotischere Programme wie die von Autodesk/Discreet (Smoke, Combustion, etc). Aber an die kam man so garnicht ran ohne gleich ein komplettes Schnittsystem zu kaufen. Aber jetzt gibt es Blackmagic DaVinci Resolve, das auch keine großen Einschränkungen hat. Ich habe mir jeden Falls vorgenommen darauf umzusteigen, wenn ich mal wieder ein Video schneiden muss. Die Blackmagic Produkte kennt man ja und die waren schon immer cool.. auch deren Kameras.
Gibt es auch für Linux! Super professionelle Schnittlösungen für Linux waren lange echt nicht zu finden.. jetzt gibt es viele.

4. Audio 2
Ja.. kann man immer gut gebrauchen. Früher gab es noch Cool Edit Pro, bevor es von Adobe gekauft wurde und zu Audition wurde. Die erste Adobe Version war noch eine 1:1 Übernahme des Programms mit geänderten Namen.

5. Grafik
Klar gibt es GIMP, das super für Fotos ist. Wer aber malen möchte ist mit Krita besser beraten. Für Zeichner wohl auch besser als Photoshop. Leider hat es keine 3D-Figuren wie Clip Studio Paint Pro.

bbcode-image
Wacom Cintiq mit Clip Studio Paint


Vielleicht baut ja jemand mal ein Plugin um Blender zu integrieren. Genau wie GIMP stammt auch Krita aus der Linux-Welt und wurde dann auf Windows portiert.
Krita hat auch Pixelart Werkzeuge, aber kann sehr viel weniger als Aseprite, dass nicht kostenlos ist, aber als Portable multiplattform Lösung seine paar Euro echt das Geld wert ist (gibt es im Humble Bundle Store). Für Windows gibt es [url=http://www.ultimatepaint.com/de/]Ultimate Paint als kostenlose EA DeluxePaint Kopie (ja EA hat mal Grafik-Software gemacht! Hatte ich mal auf einem 386er.).

bbcode-image
Animation mit Aseprite erstellt


bbcode-image
Ultimate Paint


6. Grafik RAW
Für die Bearbeitung von RAW-Fotos und als Alternative zu Lightroom gibt es noch RawTherapee für Windows und Linux. Begleitet mich seit meinen Nikon D80 Zeiten.. f*ck.. ist das schon lange her.


Der Vorteil der meisten genannten Lösungen ist einfach, dass es sie für Linux gibt, man also auch nicht mal mehr Windows als kostenpflichtige Software braucht. Ich mag Linux Mint.. wobei Windows 10 meiner Meinung nach die beste Windows Version seit NT 4.0 ist.

Unmodifiable Maps in Java

Manchmal soll Logik auf Daten einer Map zugreifen können aber nicht ändern können. Ich habe für meine State-Implementierung Action-Dispatcher eingeführt, die Daten der Action anpassen dürfen und dafür auch Daten aus dem State zum Abgleich nutzen sollen, aber an der Stelle sollen sie nicht die Möglichkeit haben den State selbst zu ändern, weil ich an der Stelle keine Änderungen tracke. Action-Dispatcher sollen schnell und leichtgewichtig sein.


Map<String, Object> stateUnmod = Collections.unmodifiableMap(this.state);
for (ActionDispatcher dispatcher: this.dispatchers) {
dispatcher.dispatch(action, stateUnmod);
}


Zum Glück kann man mit Collections sich schnell eine unmodifiable Map erstellen. Was das für die Performance bedeutet habe ich noch nicht getestet, aber ich gehe davon aus, dass das Tracken und Behandeln von Änderungen am State am Ende auf wendiger wäre.

Older posts:

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?