Jump to content

Schnittstelle und Lua


Empfohlene Beiträge

Hallo,

... hat mich doch mal interessiert, ob es in Lua auch über die Schnittstelle geht...
 

-- Kommando über Schnittstelle senden

local host, port = "127.0.0.1", 31285 -- IP und Port festlegen (31285=Kommandoport)
local socket = require("socket")      -- Biliothek "socket" einbinden
local tcp = socket.tcp()              -- TCP Client erstellen


tcp:connect(host, port);              -- Client verbinden

tcp:send("1\n")  -- Kommando "1" senden = MBS-Versionsnummer
tcp:send("20\n") -- Kommando "20" senden = ID der geöffneten Anlage
tcp:send("21\n") -- Kommando "20" senden = Info über geöffnete Anlage 

while true do                           -- Auf Antwort warten
    local s, status = tcp:receive()     -- Antwort und Status abfragen
    print(s)                            -- Antwort drucken
    if status == "closed" or status== "Socket is not connected" then -- Abbruchbedingung -> Client geschlossen oder nicht verbunden 
      print(status)
      break 
    end 
end
tcp:close()                             -- Client schließen
-- Ereignisse über Schnittstelle empfangen

local host, port = "127.0.0.1", 31286 -- IP und Port festlegen (31286=Ereignisport)
local socket = require("socket")      -- Biliothek "socket" einbinden
local tcp = socket.tcp()              -- TCP Client erstellen


tcp:connect(host, port);              -- Client verbinden

while true do                           -- Auf Antwort warten
    local s, status = tcp:receive()     -- Antwort und Status abfragen
    print(s)                            -- Antwort drucken
    if status == "closed" or status== "Socket is not connected" then -- Abbruchbedingung -> Client geschlossen oder nicht verbunden 
      print(status)
      break 
    end 
end
tcp:close()                             -- Client schließen

Da das MBS nur über ein eigeschränkes Lua verfügt, geht es da nicht direkt... ich habe es im "ZeroBrane Studio" (gibt es auch als portable Version) ausprobiert...

Anmerkung: Neugierig bin ich wegen dieser Antwort von Neo geworden,
wobei Neo gleichzeitig schreibt:

Zitat

der Grund, warum die Schnittstelle nicht die neuen Fähigkeiten von V5 unterstützt liegt darin, dass die Schnittstelle als "veraltet" gilt und in einer zukünftigen Version vermutlich entfernt wird. Mein Interesse gilt eher der Verschmelzung der Schnittstelle mit der neuen EV, sodass per Lua Netzwerkkommandos gesendet und empfangen werden können. Ein externes Programm hätte dann so Zugriff auf alle Daten, auf die auch die EV zugreifen kann. 

also sehe ich es mal als (temporäre) Möglichkeit um meinem Spieltrieb (gelegentlich) nachzukommen und mit Lua zu experimentieren... vielleicht hift es ja auch dann etwas in "einer zukünftigen Version"...

Gruß
EASY
 

Bearbeitet von EASY
Link zu diesem Kommentar
Auf anderen Seiten teilen

Bin ich sehr dankbar für die Source. Prima EASY! (y)
Wenn Neo sein Zukunftskonzept aber nicht ändert, heißt es allerdings auch, dass er die Erzeugung von Objekten nicht mehr zuläßt, was das Ende einiger Deiner Plugins bedeuten wird. Inwieweit er die Netzwerkkomponenten einbinden kann, ohne die Sicherheit des MBS zu gefährden, wird man sehen.

Gruß
  Andy

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @EASY,

super, funktioniert ausgezeichnet. (y) 

Das ist eine gute Idee, das direkt mit Lua zu programmieren. Ich habe bis jetzt mit Python ein paar Versuche gemacht.

Die Frage ist nur, wie sieht es in Zukunft aus. Wie stark kann man mit "externen Programmen" auf MBS zugreifen. (Sicherheit?)

Gruß Martin  

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hehe typisch EASY :)

Tatsächlich wird die Kommunikation, wie ihr selber schon angemerkt habt, aus Sicherheitsgründen abstrakter ablaufen. Das Aufbauen von Netzwerkverbindungen übernimmt auch in Zukunft allein das Studio, es wird jedoch ein Ereignis in der EV "Netzwerkkommando empfangen" geben, mit einem Text als Auslöser. Dieser Text enthält dabei einen beliebigen Inhalt, den das externe Programm an das Studio gesendet hat. Per Lua "return" wird daraufhin eine Antwort zurückgesendet. Welches Format der gesendete Text besitzt spielt dabei keine Rolle mehr, jede Anwendung kann ihr eigenes Protokoll implementieren.

Was die Plugins betrifft, solange es keinen vollständigen Ersatz der alten Schnittstelle gibt, werden diese noch nicht verschwinden. Im Moment sehe ich aber nicht wirklich einen großen Bedarf an zukünftigen Plugins. Sinnvoller ist eher die Integration der Plugins direkt in das Studio.

Viele Grüße,

Neo

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zumindest können wir uns eine Weile damit behelfen, die Schnittstelle zu nutzen, ohne dass wir ein extra Plugin schreiben müssen, denn Lua ist nachlesbar und muß nicht compiliert werden. Dadurch haben wir in der Tat die Möglichkeit mit V4 ein GBS zu bauen und damit eine V5 anzusteuern. Das könnte auch für unsere Videoregisseure interessant sein. Ich werde da demnächst ein kleines Beispiel einstellen. Größeres ist damit ja (noch) nicht geplant.

Gruß
  Andy

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

da mich mein Modell gerade ärgert, habe ich zum Frustabbau etwas Lua-iert...
In Anlehnung wie ich es damals in VB gemacht habe, bin ich gerade dabei es etwas modularer aufzubauen.
So sieht jetzt mein "MBS-Kommando senden" aus...
 

-- Kommando über Schnittstelle senden

local host, port = "127.0.0.1", 31285 -- IP und Port festlegen (31285=Kommandoport)
local socket = require("socket")      -- Biliothek "socket" aufrufen
local tcp = socket.tcp()              -- TCP Client erstellen
local ok,status                       -- Verbindung ok, status liefert evtl Fehlermeldung
ComAnswer={}                          -- Antworttabelle (global!)

ok,status=tcp:connect(host, port)              -- Client verbinden
if ok == nil then                              -- Verbindung hergestellt?...       
  print("Verbindungsfehler: "..status)         -- ... wenn nicht Fehlermeldung + Programm beenden 
  os.exit()
end

function SendCom (parameter)                  -- Funktion Kommando senden
  ComAnswer={}                                -- Antworttabelle leeren
  ok,status=tcp:send(parameter.."\n")         -- Kommando senden
  if ok==nil then                             -- Verbindung fehlgeschlagen?
    ComAnswer[1]=status                       -- Fehlermeldung zwischenspeichern
    return false                              -- "false" zurückgeben
  end
  local s                                     -- temp. Variable für Antwort
  s,status=tcp:receive()                      -- Antwort abfragen
  if status ~=nil then                        -- Verbindung fehlgeschlagen?
    ComAnswer[1]=status                       -- Fehlermeldung zwischenspeichern
    return false                              -- "false" zurückgeben
  end
  s:gsub("[^;]+",function(c) table.insert(ComAnswer,c) end) -- Antwort in Tabelle umwandeln; ";" als Trennungszeichen; "+"= ganzer Ausdruck
  if ComAnswer[1]=="0" then                   -- Antwort enthält Fehler (z.B. ungültiges Kommando)
    table.remove(ComAnswer,1)                 -- Fehlermeldung zwischenspeichern
    return false                              -- "false" zurückgeben
  end
  if #ComAnswer>1 then                        -- Anz. Elemente in Antworttabelle>1?...
    table.remove(ComAnswer,1)                 -- .. 1. Element löschen (1. Element = 1 oder 0 für gesendetes Kommando ist gültig?) 
    return true                               -- "true" zurückgeben
  else
    ComAnswer[1]="Kein Rückgabeparameter oder leere Liste" -- Antwort hat keine weiteren Elemente (z.B. Kommando 51 [MBS-Animation ein/aus])
    return true                                            -- "true" zurückgeben
  end
end

... und dies wäre dann ein einfaches Beispiel für das Hauptprogramm...
 

require("MBS-Kommando senden") -- Datei "MBS-Kommando senden.lua" einbinden [Ohne Pfad = gleiches Verzeichnis!] 

if SendCom("100;2") then              -- Kommando senden ohne Fehler?... ["100"-> Objektliste; "2" -> Rollmaterial]
  for i,v in ipairs(ComAnswer) do     -- Antworttabelle ausgeben.
    print(i,v)
  end
else
  print("Fehler: "..ComAnswer[1])     -- Im Fehlerfall: Meldung ausgeben
end

... da ich in Lua in den Anfängen stecke, wenn jemand Verbesserungsvorschläge hat... gerne!

Gruß
EASY

Bearbeitet von EASY
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb EASY:

... da ich in Lua in den Anfängen stecke, wenn jemand Verbesserungsvorschläge hat... gerne!

Spontan habe ich nur zwei Kleinigkeiten:

statt if ok == nil then kannst du auch schreiben if not ok then, denn nil wird in Lua als false gewertet.

Variablen sind in Lua per se global angelegt. Lokale Variablen muss man explizit erzeugen.
Deshalb wäre es besser, du würdest 

local ok, status = tcp:connect(host, port)

schreiben. Das Schlüsselwort local deklariert alle dahinter aufgezählten Variablen als lokal

Funktionsargumente, Iteratoren etc. sind natürlich auch in Lua per se lokal definiert.

Bearbeitet von Goetz
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo EASY,
für jenes Spezialprogramm bräuchten wir das Ganze zweimal. Einmal mit 31285/21286 und einmal - jo, keine Ahnung, ich habe 31287/31288 genommen und V4 dann damit konfiguriert. Das ging in C++ - ich hoffe die zwei Ports beißen nichts anderes. Könntest Du das hinkriegen?
Kannst ja selbst mal einen Versuch machen. In V4 die Ports anpassen und ein Schalterchen einbauen. In V5 ein Signal reinsetzen. Beide Programme und das Lua-Programm starten. Im Hauptprogramm das Ereignis des Schalter schaltens von V4 im Ereignisport abfangen und darauf ein Kommando Signal schalten an V5 schicken.
Wie gesagt, in C++ habe ich das am Laufen. Aber Lua hat eindeutig den Vorteil, dass es transparent ist. In C++ könnte man auch böse Dinge verstecken. Da will ich gar nicht in Verdacht kommen.

Gruß
  Andy

p.s.: Anmerkung dazu: in C++ braucht's echtes Multithreading, da die rcv-Funktion zum Abholen von Daten in der Tat hängt, bis was da ist. Ich weiß nicht, wie das in Lua ist.

Bearbeitet von Andy
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @Goetz,

... danke fürs drüberschauen und die Hinweise.

vor 15 Minuten schrieb Goetz:

Variablen sind in Lua per se global angelegt. Lokale Variablen muss man explizit erzeugen.
Deshalb wäre es besser, du würdest 


local ok, status = tcp:connect(host, port)

schreiben. Das Schlüsselwort local deklariert alle dahinter aufgezählten Variablen als lokal

... da ich etwas aus der VB Ecke komme, definiere ich eigentlich gerne alle Variablen zum Anfang...
... und da habe ich schon in Zeile 6...

local ok,status                       -- Verbindung ok, status liefert evtl Fehlermeldung

... mein Hintergedanke war eigentlich, daß sie innerhalb vom "Modul" lokal bleiben sollen, da sie bei

ok,status=tcp:connect(host, port)              -- Client verbinden

und auch innerhalb der Funktion auftreten... oder habe ich da einen Denkfehler?

@Andy... da neugierig...werde ich es mal ausprobieren... wobei sich mir noch nicht ganz erschließt, warum ich von V4 aus etwas in V5 ansteuern soll:/...
(... kann auch daran liegen, daß mir ein "GBS" gerade nicht viel sagt :( [immer noch kein Anlagenbauer9_9]... aber wenn es BahnLand gefällt... ist schon verdächtig;)

Gruß
EASY
 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @EASY,

das "Hallo" war anders gemeint, als es leider rübergekommen ist. Ich bin irgendwie nach dem "Hallo" unbeabsichtigt auf die Absendetaste (oder eine irgendwie geartete Tastenkombination, die das Absenden ausgelöst hat) gekommen. Die anschließende Antwort ist dann auch verloren gegangen, weil ich vor dem Absenden versucht hatte, Deine inzwischen eingegangene Antwort zu lesen, bevor ich meine absende. Doch das funktioniert anscheinend nur bei neuen Kommentaren und nicht bei solchen, die zur Korrektur geöffnet wurden. Deshalb lasse ich nun das "Hallo" oben einfach stehen, und schreibe hier einen neuen Kommentar.

Ich hatte im letzten Kommentar vor, folgendes zu schreiben:

Das "Gefällt mir" bezieht sich darauf, dass sich wohl auch Lua eignet, über eine Remote-Schnittstelle eine Verknüpfung zwischen einer MBS-Anlage und einer weiteren steuernden MBS-Instanz anzulegen. Dies wäre eine weitere Variante gegenüber einem bereits zu Zeiten des 3D-Eisenbahnplaners von @Franz bereitgestellten Steuerungsprogramm, das dann im MBS nicht mehr funktionierte, und gegenüber der Anbindung von RocRail, jedoch mit dem gravierenden Vorteil, dass man sich auch bei der Steuerung weiterhin innerhalb des MBS (wenn auch in einer zweiten Instanz) bewegt und nicht eine völlig andere Programmschnittstelle benötigt.

Andererseits besitzt diese Idee denselben Nachteil wie alle anderen "externen" Steuerprogramme auch: Jede Kommunikation hinwärts (Steuerung eines Elements auf der Anlage durch ein GBS-Element im steuernden Programm)  und herwärts (Anzeige eines Zustands/einer Zustandsänderung auf der Anlage im GBS) benötigt eine im Steuerprogramm hergestellte Verbindung zwischen GBS-Element und korrespondierendem Anlagen-Element, die explizit aufgebaut werden muss. Die Möglichkeit, einen GBS-Baustein im Idealfall einfach mit dem korrespondierenden Anlagenelement zu "verbinden" oder die Steuerung/Anzeige über Schlagwort-basierte oder parametrisierte Ereignisdefinitionen Auslöser-bezogen zu realisieren, gibt es meiner Einschätzung nach jedoch nur, wenn beide kommunizierenden Institutionen im selben MBS vereinigt sind.

Deshalb würde ich in jedem Fall die Realisierung eines zweiten "Kamera-Fensters" im Modellbahn-Studio (ein Fenster für die Anlagen-Kamera, das zweite für die GBS-Kamera) durch @Neo bevorzugen.

Viele Grüße - und sorry für das "Hallo", das sich selbständig gemacht hat
BahnLand

Bearbeitet von BahnLand
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb EASY:

wobei sich mir noch nicht ganz erschließt, warum ich von V4 aus etwas in V5 ansteuern soll

Hi EASY,
zweimal V5 geht halt nicht. Geht auch nur um's Prinzip und darum, wie weit man das da noch treiben kann. Immerhin gibt es da ja auch noch eine http-Verbindung...

Gruß
  Andy

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 3 Stunden schrieb EASY:

oder habe ich da einen Denkfehler?

Nein - vollkommen richtig. Ich hatte das nur übersehen. Pardon.

Ich hatte die Funktionsdefinition SendCom() überflogen und dort kein local gesehen.

 

Da du die Variablen in der Funktion neu befüllst, kannst du sie übrigens bedenkenlos beim Verlassen der Funktion löschen. Also innerhalb der Funktion local anlegen. Das hat - soweit mein bisheriges Verständnis dieser Materie - zwei Vorteile.

  1. Du kannst den selben Namen für weitere lokale Variablen an anderen Orten nutzen, ohne Konflikte befürchten zu müssen.
  2. Lokaler Speicher ist schnell, aber auch wertvoll. Deshalb ist es gut, den nur für den Moment zu beanspruchen, in dem man eine Variable wirklich braucht. Wenn sie beim nächsten Funktionsaufruf einen neuen Wert bekommt und der letzte Wert bedeutungslos ist, dann kann man die Variable ebenso gut in dem Moment frisch anlegen, in dem sie eingesetzt wird. Oftmals sind die Variablen ja nur Zwischenträger, um Daten von A nach B zu bringen.

Ich glaube, dass es generell eine gute Praxis ist, die Lebensdauer von Variablen kurz zu halten. Wenn der aktuelle Wert nicht mehr benötigt wird - weder direkt noch indirekt (für Additionen etc.), dann ist die Variable passé. Dass ich später unter dem selben Namen wieder einen Wert bilde, macht keinen Unterschied. Ich muss nicht permanent ein Plätzchen frei halten.

 

Ich könnte mir auch vorstellen, die Tabelle ComAnswer() ebenfalls lokal in der Funktion SendCom() zu erzeugen und mit return an den Aufrufer zu übergeben. Das wäre meines Erachtens sauberer, weil diese Tabelle ebenfalls bei jedem Funktionsaufruf neu gebildet werden muss. Und das ist mit einer lokalen Tabelle innerhalb der Funktion automatisch gewährleistet. Der Empfänger ist dann eine neue lokale Adresse beim Aufrufer. Dort wird die Tabelle für die print-Ausgabe verwendet und anschließend der Müllabholung überlassen.

 

Zu print() habe ich auch noch einen Vorschlag. Die Funktion print() ist eine echte Bremse. Sie kostet viel Rechenzeit. Deshalb ist es ratsam, zuerst den gesamten Ausgabetext in einem einzigen String zusammenzufassen und diesen dann mit einem einzigen print() auszugeben. Lua hat dafür etwas sehr nettes: table.concat()

Beispiel = {"Lua", "und", "die", "weite", "Welt"}

s = table.concat(Beispiel, " ")
print(s)

Das zweite Argument für table.concat ist das einzusetzende Trennzeichen. Im obigen Beispiel ist es ein Leerzeichen.

Die "alles in einen String" Methode ist aber auch ratsam, wenn du z.B. in einer Schleife wiederholt print() verwendest. Bau mit der Schleife lieber den String zusammen und gib ihn dann einmal komplett aus.

 

Weil ich oft missverstanden wurde: All das meine ich in keiner Weise als Kritik. Was du programmiert hast, ist alles prima.
Ich will nur gerne beitragen, was ich entdeckt habe und nützlich finde.

Viele Grüße
Götz

Bearbeitet von Goetz
Schreibfehler korrigiert
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

vor 1 Stunde schrieb BahnLand:

Viele Grüße - und sorry für das "Hallo", das sich selbständig gemacht hat

... hätte als Reaktion auch gut gepasst:D

vor einer Stunde schrieb Andy:

Geht auch nur um's Prinzip und darum, wie weit man das da noch treiben kann

... bei so etwas bin ich immer gerne dabei... auch Neo war schon mal überrascht, was man mit seinem Programm (noch) so alles machen kann...

vor 28 Minuten schrieb Goetz:

Weil ich oft missverstanden wurde: All das meine ich in keiner Weise als Kritik. Was du programmiert hast, ist alles prima.
Ich will nur gerne beitragen, was ich entdeckt habe und nützlich finde.

... ich habe ja darum gebeten. Andere Sichtweisen bringen immer etwas... und es ist ja nicht zwingend, daß man sie 1:1 übernimmt....
... das "print()" ist momentan auch nur ein Platzhalter, damit überhaupt etwas passiert... in diesem Fall ist es eben zur Überprüfung der Richtigkeit besser die Ausgabetabelle als Einzelelemente auszugeben. Die Schnittstelle liefert alles in einem String zurück (wenn ich z.B. alle Objekte auslese, kann dieser ziemlich lang sein) und so kann ich überprüfen, ob der String für die weitere Bearbeitung richtig zerlegt wurde....

Gruß
EASY

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

ich habe die Kommunikation über die Schnittstelle zwischen V4 und V5 mal rudimentär(!) hergestellt.
Der Testaufbau sieht folgendermaßen aus:
Testaufbau.thumb.jpg.08e5ce64412cbf9b9ac6cba1721d0fe9.jpg

... wird der Schalter im MBS-V4 auf "ein" gestellt fährt die Lok im MBS-V5 vorwärts und bei Schalter "aus" rückwärts.
... wird der Schalter im MBS-V5 auf "ein" gestellt fährt die Lok im MBS-V4 vorwärts und bei Schalter "aus" rückwärts.
(den Testaufbau hier einzustellen erspare ich mir... beim Nachbau unbedingt auf die Namen achten!)

Das Skript dazu ist auf das nötigste beschränkt...
 

-- Kommunikation zwischen MBS-V4 und MBS-V5

local socket = require("socket")      -- Biliothek "socket" aufrufen
local tcp4e = socket.tcp()            -- TCP Client erstellen (MBS-V4 Ereignisse)
local tcp4c = socket.tcp()            -- TCP Client erstellen (MBS-V4 Kommando)
local tcp5e = socket.tcp()            -- TCP Client erstellen (MBS-V5 Ereignisse)
local tcp5c = socket.tcp()            -- TCP Client erstellen (MBS-V5 Kommando)
local ok,status,s4,s5


ok,status=tcp4e:connect("127.0.0.1", 31288) -- Client verbinden (MBS-V4 Ereignisse [Port im MBS-V4 auf 31288 gestellt])
if not ok then
  print("Verbindungsfehler V4: "..status)
end

ok,status=tcp4c:connect("127.0.0.1", 31287) -- Client verbinden (MBS-V4 Kommando [Port im MBS-V4 auf 31287 gestellt])
if not ok then
  print("Verbindungsfehler V4: "..status)
end

ok,status=tcp5e:connect("127.0.0.1", 31286) -- Client verbinden (MBS-V5 Ereignisse [Port 31286=Standardeinstellung])
if not ok then
  print("Verbindungsfehler V5: "..status)
end

ok,status=tcp5c:connect("127.0.0.1", 31285) -- Client verbinden (MBS-V5 Kommando [Port 31285=Standardeinstellung])
if not ok then
  print("Verbindungsfehler V5: "..status)
end


-- Achtung!!! ab hier Endlosschleife
while true do
  tcp4e:settimeout(0.01,"b")                                         -- Timeout für tcp4e ( bezogen auf tcp4e:receive())
  tcp5e:settimeout(0.01,"b")                                         -- Timeout für tcp5e ( bezogen auf tcp5e:receive())
  
  s4,status= tcp4e:receive()                                         -- tcp4e abfragen
  if s4~=nil then                                                    -- wurde etwas gesendet?
    local EventAnswerV4={}                                           -- Antworttabelle = leer
    s4:gsub("[^;]+",function(c) table.insert(EventAnswerV4,c) end)   -- Antworttabelle erstellen
    if EventAnswerV4[1]=="210" and EventAnswerV4[2]=="ReglerV5" then -- Event "210" (Steuerobjekt Wert geändert) und Namen abfragen
      local v5=(EventAnswerV4[3]-0.5)*200                            -- Geschwindigkeit für Lok in MBS-V5 
      local ComV5=table.concat({"371","LokV5","0",v5},";").."\n"     -- String zum Senden erzeugen (Lokgeschwindigkeit setzen) 
      print(ComV5)
      ok,status=tcp5c:send(ComV5)                                    -- Kommando zu MBS-V5 senden
      if not ok then                                                 -- Senden ok? 
        print("Verbindungsfehler V5: "..status)
      end
    end
  end
  
  s5,status= tcp5e:receive()                                         -- tcp5e abfragen
  if s5~=nil then                                                    -- wurde etwas gesendet?
    local EventAnswerV5={}                                           -- Antworttabelle = leer
    s5:gsub("[^;]+",function(c) table.insert(EventAnswerV5,c) end)   -- Antworttabelle erstellen
    if EventAnswerV5[1]=="210" and EventAnswerV5[2]=="ReglerV4" then -- Event "210" (Steuerobjekt Wert geändert) und Namen abfragen
      local v4=(EventAnswerV5[3]-0.5)*20                             -- Geschwindigkeit für Lok in MBS-V4 
      local ComV4=table.concat({"371","LokV4","0",v4},";").."\n"     -- String zum Senden erzeugen (Lokgeschwindigkeit setzen)
      print(ComV4)
      ok,status=tcp4c:send(ComV4)                                    -- Kommando zu MBS-V4 senden
      if not ok then                                                 -- Senden ok? 
        print("Verbindungsfehler V4: "..status)
      end 
    end
  end  
end

 

Am 9.1.2020 um 15:58 schrieb Andy:

p.s.: Anmerkung dazu: in C++ braucht's echtes Multithreading, da die rcv-Funktion zum Abholen von Daten in der Tat hängt, bis was da ist. Ich weiß nicht, wie das in Lua ist.

... bräuchte es in Lua auch, da auch hier gewartet wird, bis etwas kommt.

Ich habe dieses Problem "umgangen" indem ich dem "receive()" ein "timeout" mit auf den Weg gegeben habe. Bei mir sind es momentan 0,01 Sekunde. Ich habe es versuchsweise mal mit 0 Sekunden probiert... Lua kann den Rechner ganz schön belasten wenn es eine Enlosschleife fährt:o!

Ich betrachte mein "Werk" mal als Pionierarbeit um zu zeigen, daß es prinzipiell geht... und frage mal neugierig nach, ob sich schon mal jemand mit Lua und Multithreading beschäftigt hat...

Gruß
EASY

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo EASY,
erstmal Applaus! (y) Ich schau's mir morgen mal in aller Ruhe an.
Was das Multithreading angeht, finde ich ein paar Lua-libraries als GitHub-Projekte. Machbar muß es also sein.

Gruß
  Andy

p.s.: Irgendwie gibt's da sehr unterschiedliche Meinungen und Wege (die dann in 'terrific territory' enden können...), obwohl eine 'coroutine' eigentlich wie eine machbare Lösung aussieht.
Ansonsten wird's für das Experiment doch reichen. Eine Endlosschleife wird da sowieso immer bleiben.

Bearbeitet von Andy
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Andy,

vor 21 Stunden schrieb Andy:

obwohl eine 'coroutine' eigentlich wie eine machbare Lösung aussieht.

... habe ich mir auch schon mal angeschaut. Bisher verstehe ich es allerdings eher als eine Art "Verteiler" als wie Multithreading (man muß eine coroutine anhalten, damit die nächste weiter arbeiten kann)[?]...

...da ich momentan zu diesem Thema in Lua einiges an Möglichkeiten angesehen habe, mir allerdings dazu noch kein Plan eingefallen ist, lasse ich es erst einmal auf mich einwirken (festbeißen bringt nicht wirklich voran)...

bis dahin...

vor 21 Stunden schrieb Andy:

Ansonsten wird's für das Experiment doch reichen. Eine Endlosschleife wird da sowieso immer bleiben.

P.S. Lua kann man auch in der Pfeiffe rauchen... dann kommt man auf einem Lua-Trip:D...

Gruß
EASY

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @EASY, @Andy,

vielleicht ist dieser Beitrag interessant.

da steht:

Effil is a multithreading library for Lua. It allows to spawn native threads and safe data exchange. Effil has been designed to provide clear and simple API for lua developers.

Effil supports lua 5.1, 5.2, 5.3 and LuaJIT. Requires C++14 compiler compliance. Tested with GCC 4.9+, clang 3.8 and Visual Studio 2015.
 

Gruß Martin

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen.

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...