ChaosConsole

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

hamZta

Administrator

Betreff: ChaosConsole

BeitragSo, Jul 19, 2009 3:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey!

Hab die letzten zwei Tage was praktisches (hoffentlich) gebastelt: Eine Console, ähnlich denen aus Quake oder CS zum einfachen Einbinden und Debuggen zur Laufzeit.

~ Features ~

  • Zugriff auf bereits erstellte BlitzMax-Types zur Laufzeit (Felder auslesen bzw. verändern und Methoden aufrufen)
  • Neue Objekte aus Types erstellen
  • Funktionen aufrufen


~ Konsolenbefehle ~

  • set objektname.field wert
    Setzt das Field eines Objekts auf "wert"
  • print arg1 arg2 arg3 ...
    Gibt alle Argumente aus
  • dump objektname
    Gibt alle Felder eines Objektes mit ihren Werten aus
  • create type name
    Erstellt eine Instanz des Types "type" mit dem Namen "name"
  • delete objektname
    Löscht eine mit der o.g. Methode erstellte Instanz wieder. Wird nur wirklich gelöscht wenn keine anderen Verweise auf das Objekt existieren.
  • list
    Listet alle registrierten Objekte und Funktionen auf
  • save dateiname
    Speichert den Inhalt der Konsole in einer Datei
  • assert value1 value2 message
    Wenn value1 nicht gleich value2 ist wird message ausgegeben (und die Ausführung des Scripts ggf. unterbrochen)
  • run filename
    Führt das Script filename aus


$obj.field als Argument gibt den Wert des Feldes field zurück.
$obj.field[index] als Argument gibt den Wert des Arrays field an der Stelle index zurück

Lässt man bei Arrays den Operator [index] weg so wird der Inhalt des Arrays als eine Liste der Form "[0, 1, 2, 3, ...]" zurückgegeben.

~ Beispiel ~
BlitzMax: [AUSKLAPPEN]
SuperStrict

Import Chaos.Console

Graphics 1024, 768

Rem
Wir definieren einen Type zum Testen
Der Typ zeichnet Bälle mit zufälliger Größe, Position und Farbe
Mit changeColor() kann man eine neue, zufällige Farbe ermitteln lassen
End Rem

Type TBall

Global _list:TList = New TList
Field _colR:Byte, _colG:Byte, _colB:Byte
Field _rad:Int
Field _x:Int, _y:Int

Method New()
_x = Rand(0, 1024)
_y = Rand(0, 768)
_colR = Rand(0,255)
_colG = Rand(0,255)
_colB = Rand(0,255)
_rad = Rand(20, 200)
TBall._list.AddLast(Self)
End Method

Method draw()
SetColor _colR, _colG, _colB
DrawOval _x-_rad/2, _y-_rad/2, _rad, _rad
End Method

Method changeColor()
_colR = Rand(0,255)
_colG = Rand(0,255)
_colB = Rand(0,255)
End Method

End Type

Rem
Diese Funktion rufen wir später direkt aus der Konsole auf
Jede Funktion die von der Konsole aufrufbar sein soll muss diese Signatur haben:
Function <name>:Int(TChaosConsole, String[])
Der erste Parameter ist eine Referenz auf die Konsole die die Funktion aufruft,
der zweite ein String-Array mit den Parametern.
End Rem

Function consolePrint(con:TChaosConsole, args:String[])
con.output(args[0])
End Function

Rem
Neue Instanz von TBall erstellen
End Rem

Global b1:TBall = New TBall

Rem
Neue Instanz der Konsole erstellen
End Rem

Global con:TChaosConsole = New TChaosConsole
con.setBackgroundColor(0, 50, 0, 0.5) ' Setzt die Hintergrundfarbe und Transparenz
con.setFontColor(0, 255, 0) ' Setzt die Schriftfarbe

Rem
Wir registrieren die Instanz unseres Types bei der Konsole und geben ihr einen Namen.
Über diesen Namen können wir später aus der Konsole zugreifen.
End Rem

con.registerObject("ball1", b1)

Rem
Jetzt registrieren wir die oben definierte Funktion unter dem Namen "print".
Zusätzlich geben wir an, dass diese Funktion ein Minimum von einem Parameter braucht.
Gibt der User weniger Parameter schreit die Konsole Wink
End Rem

con.registerFunction("print", 1, consolePrint)

' Hauptschleife
While Not KeyHit(KEY_ESCAPE)

' Alle Bälle in der Liste durchgehen und zeichnen
For Local b:TBall = EachIn TBall._list
b.draw()
Next

' Konsole updaten & zeichnen
' Mit F1 lässt sich die Konsole ein- bzw. ausklappen
con.update(KEY_F1)

Flip;Cls

Wend


Eingaben/Ausgaben der Konsole:
Code: [AUSKLAPPEN]
~ ChaosConsole ~
Version: 0.1-rel_1
-----------------------------------------------------------
Registered object 'console'
Registered object 'ball1'
> list
Registered objects:
- ball1:TBall
- console:TChaosConsole
Registered functions:
- print
> dump ball1
Object ball1:TBall
   _colB:Byte = 146
   _colG:Byte = 38
   _colR:Byte = 177
   _rad:Int = 50
   _x:Int = 429
   _y:Int = 163
> set ball1._rad 70
Set 'ball1._rad' to '70'
> ball1.changeColor
> ball1.changeColor
> print $ball1._rad
70
> create TBall ball2
Created new object from type 'TBall'
> set ball2._rad $ball1._rad
Set 'ball2._rad' to '70'
> list
Registered objects:
- ball1:TBall
- ball2:TBall
- console:TChaosConsole
Registered functions:
- print
> print "Hallo! :)"
Hallo! :)
> save consolelog.txt

Ich liste also erstmal auf, welche Objekte bei der Konsole registriert sind, in unserem Fall ball1 und console. Letzteres wird automatisch registriert und ist die Referenz auf die Konsole selbst. Ersteres ist unser Objekt ball1 welches wir ja im BlitzMax-Source erstellt haben.

Dann lasse ich mir mittels "dump ball1" alle Felder des Objekts ausgeben. Mit "set ball1._rad 70" erhöhe ich den Radius des Kreises auf 70. Mit "print $ball1._rad" rufe ich unsere definierte Funktion "consolePrint" auf und zwar mit dem Wert des Feldes _rad der Instanz ball1 (um an den Wert des Feldes zu kommen brauchen wir das $-Zeichen).
Dann erstelle ich eine neue Instanz des Types TBall und nenne sie "ball2". Mit "set ball2._rad $ball1._rad" setze ich den Radius des neuen Kreises ebenfalls auf 70.
Ich lasse mir nochmal alle Objekte auflisten, jetzt taucht auch ball2 in der Liste auf. Dann grüße ich noch recht freundlich und speichere den Inhalt der Konsole in einer Datei Wink

~ Tasten ~
Ich hab mir Mühe gegeben, das Arbeiten mit der Konsole so komfortabel wie möglich zu machen:
Die Eingabe funktioniert ganz normal per Tastatur. Mit Links bzw. Rechts kann man den Cursor bewegen, mit Backspace oder Delete wie gewohnt löschen. Mit Home/Pos1 springt man an den Anfang der Zeile, mit End ans Ende. Per Page Up/Page Down kann man in der Konsole scrollen.
Mit Rauf/Runter kann man in der Befehlshistory blättern, alle Befehle die man mit Enter abschickt, werden gespeichert und müssen so nicht doppelt getippt werden.

~ ToDo ~

  • Autovervollständigung per Tabulator
  • Möglichkeit, eine andere Schriftart zu verwenden
  • Parser verbessern (Mathematische Ausdrücke, Bedingungen, etc...)


~ Updates ~
Zitat:
0.2-rel_1
- New command: print <arg1> <arg2> ..., replaces "get"
- New command: assert <value1> <value2> <msg>, compares two values and breaks on difference.
- New command: run <filename>, executes a file
- Support for one-dimensional arrays added (e.g. set obj.field[index] value)
- ChaosConsole now automatically breaks long lines

0.1-rel_1
- Initial Release


~ Download ~
Modul, inkl. Dokumentation, Beispiel und Source: Hier!

Vielen Dank für die Aufmerksamkeit, um Feedback wird gebeten Smile

lg,
hamZta
  • Zuletzt bearbeitet von hamZta am Mo, Jul 27, 2009 19:56, insgesamt 2-mal bearbeitet

MVB

BeitragMo, Jul 20, 2009 15:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann ich sehr gut gebrauchen und scheint sehr gut zu funktionieren, soweit ich das bisher testen konnte. Danke!
aquamonit.de|BlitzMax|MaxGUI

hamZta

Administrator

BeitragMo, Jul 27, 2009 20:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Update 0.2-rel_1
Zusammengefasst die Änderungen:

  • Neuer Befehl "print". Macht die Benutzung von "get" obsolet, gibt alles was danach kommt aus.
    Beispiel:
    Code: [AUSKLAPPEN]
    > print "Feld 'bla' = " $obj.bla
    Feld 'bla' = 30

  • Neuer Befehl "assert". Vergleicht zwei Werte und gibt bei Nichtübereinstimmung eine Nachricht aus.
    Beispiel:
    Code: [AUSKLAPPEN]
    > assert $obj.bla 20 "Feld bla ist nicht 20!"
    Assert failed: Feld bla ist nicht 20!

    Steht der Befehl in einem Script das mit "run" ausgeführt wird, so wird die Ausführung an dieser Stelle unterbrochen wenn der Vergleich fehlschlägt.
  • Neuer Befehl "run". Führt ein externes Script aus.
    Beispiel:
    Code: [AUSKLAPPEN]
    > run script1.txt

    In script1.txt stehen beliebige Konsolenbefehle untereinander, diese werden dann interpretiert.
  • Unterstützung für eindimensionale Arrays.
    Folgender Type sei in den Beispielen als "ball1" registriert:
    Code: [AUSKLAPPEN]
    Type TBall
        Field _coords:Int[] = [25, 34, 3]
    End Type


    Beispiel 1:
    Code: [AUSKLAPPEN]
    > print "Array: " $ball1._coords
    Array: [25, 34, 3]
    > print "Arraywert: " $ball1._coords[1]
    Arraywert: 34
    > set ball1._coords[1] 35
    Set ball1._coords[1] to '35'

  • Überlange Zeilen werden jetzt automatisch umgebrochen.
Blog.

hamZta

Administrator

BeitragDo, Sep 17, 2009 16:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Update 0.3-rel_1
Gesamter Rewrite des Parserteils.

Der Parser wurde ausgetauscht, die Console basiert nun auf der flexiblen und schnellen Sprache Lua die in vielen modernen Spielen zum Einsatz kommt.

Alle Sachen die man in der Konsole eingibt werden von Lua ausgewertet und - wenn fehlerfrei - ausgeführt.

Man kann z.B. direkt in der Console Funktionen definieren, Bedingungen auswerten, Schleifen durchlaufen und und und. Des weiteren natürlich externe Lua-Skripte ausführen und eigene Funktionen aufrufen. Natürlich hat man immer noch Zugriff auf die alten Features der Console (hauptsächlich Zugriff auf Objekte).

Sollte jemand in seinem Projekt bereits Lua verwenden so bietet sich die Möglichkeit, die Console per einfachem Methodenaufruf an den eigenen Lua-State anzubinden. Alle nötigen internen Hilfsfunktionen und Einstellungen werden dann automatisch erstellt bzw. vorgenommen. Nutzt man diese Möglichkeit, so hat man damit Vollzugriff auf alle in den eigenen Lua-Skripten definierten Funktionen, Variablen und Tabellen.
Dabei werden Ausgaben aus Lua heraus (Mit print oder io.write) direkt in die Console umgeleitet.

Von der Verwendung her hat sich wenig geändert, ein Beispiel liegt wieder bei.

Zusätzlich kann man jetzt noch eine eigene Schriftart verwenden, einfach mit myConsole.setFont(<TImageFont>) setzen. ChaosConsole hängt sich dabei nondestruktiv in den Zeichenprozess ein, alle Änderungen an Blendmodi, Farben, Schriften oder Skalierungen werden nach dem Zeichnen wieder rückgängig gemacht.

~ Befehle in Konsole und Luaskripten ~

  • ccOutput(text) - Gibt text in der Konsole aus. Alternativ dazu kann man die Lua-Standardfunktion print oder io.write verwenden.
  • ccObjGet(obj, field) - Gibt den Wert des Feldes field vom Objekt obj zurück. Muss zuvor mit registerObject registriert worden sein.
  • ccObjSet(obj,field,value) - Setzt den Wert des Feldes field vom Objekt obj auf value.
  • ccObjDump(obj) - Gibt alle Felder eines Objektes mit ihren Werten aus.
  • ccObjCreate(type, name) - Erstellt eine Instanz des Types "type" mit dem Namen "name".
  • ccObjDelete(name) - Löscht eine mit der o.g. Methode erstellte Instanz wieder. Wird nur wirklich gelöscht wenn keine anderen Verweise auf das Objekt existieren.
  • ccObjList() - Listet alle registrierten Objekte und Funktionen auf.
  • ccObjToTable(instanz, tablename) - Erstellt aus einer Instanz eine Lua-Table, siehe Beispiel unten.
  • ccClear() - Leert die Console.


~ Beispiele ~
ccObjToTable(instanz, tablename):
Hat man eine Instanz des Types TTest:
BlitzMax: [AUSKLAPPEN]
Type TTest
Field _x:Int, _y:Int
Field _name:String
End Type

Local myTest:TTest = New TTest
myTest._name = "Testtype"

und ruft dann in der Konsole "ccObjToTable("myTest", "luaMyTest")" (inkl. Anführungsstriche um die Argumente!) dann erhält man eine Lua-Table mit den Werten aus der Instanz.
In der Console "print("Name: " .. luaMyTest._name)" spuckt damit "Name: Testtype" aus.
Achtung: Die erstellte Tabelle ist nur ein Abbild der Instanz, die beiden Objekte sind (noch) nicht miteinander verknüpft. Änderungen wirken sich also nicht auf beide aus. Auch Methoden können noch nicht aufgerufen werden.

Beispiel aus dem Sample:
Code: [AUSKLAPPEN]
~ ChaosConsole ~
Version: 0.3-rel_1
Lua: Lua 5.1.4
Copyright (C) 1994-2008 Lua.org, PUC-Rio
-----------------------------------------------------------
Registered object 'console'
Registered object 'ball1'
> ccObjDump("ball1")
Object ball1:TBall
   _colB:Byte = 146
   _colG:Byte = 38
   _colR:Byte = 177
   _rad:Int = 50
   _x:Int = 429
   _y:Int = 163
> ccObjToTable("ball1", "luaBall")
> print(luaBall)
table: 002DFA38

> print(luaBall._x)
429

> if (tonumber(luaBall._x) > 400) then luaBall._x = 400 end
> print(luaBall._x)
400

> if (tonumber(ccObjGet("ball1", "_x")) > 400) then ccObjSet("ball1", "_x", 400) end -- so ist's richtig ;)
> ccObjDump("ball1")
Object ball1:TBall
   _colB:Byte = 146
   _colG:Byte = 38
   _colR:Byte = 177
   _rad:Int = 50
   _x:Int = 429
   _y:Int = 163
> ccObjSet("ball1", "_r", 100)
Error setting field value: No such field '_r'
> ccObjSet("ball1", "_rad", 100)
> for i=1,5 do print("Schleife!") end
Schleife!
Schleife!
Schleife!
Schleife!
Schleife!

> print(5+(8*9.43)+math.sin(87.434)*10)
75.379539814151

> ccSave("output.txt")


~ Download ~
Download gibt's hier
Kompiliert für Windows und MacOS (PPC und Intel), Linux folgt.
Blog.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group