Anglescript fragen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
fkrauthan
Beiträge: 38
Registriert: 28.02.2009, 13:34
Alter Benutzername: fkrauthan
Kontaktdaten:

Anglescript fragen

Beitrag von fkrauthan »

Hallo,
Ich hätte mal eine Frage. Ich habe schon lange gegoogelt und die Doku gelesen. Allerdings Kapiere ich es da nicht so ganz. Ich will folgendes mit Anglescript machen.
Ich habe 2 C++ Klassen. Nun will ich eine Referenz auf die 1. C++ Klasse an eine Anglescript methode übergeben. Diese Methode mit Angelscript soll dann aus dieser Klasse die Funktionen aufrufen, um z.b. einige Variablen zu setzen. Nun stellt dann noch zusätzlich die diese C++ klasse eine Funktion z.b. createClass2() welche eine referenz auf die 2. C++ klasse zurück gibt, welche ich dann ebenfalls durch die Funktionen mit variablen füllen will. Weiß jemand wie das geht? Oder gibt es doch irgendwo ein Tutorial wie man das am besten umsetzt? Schonmal jetzt danke.
Grüße,
fkrauthan
Benutzeravatar
Thoran
Establishment
Beiträge: 224
Registriert: 15.05.2009, 12:51
Wohnort: Stuttgart
Kontaktdaten:

Re: Anglescript fragen

Beitrag von Thoran »

Ich bin zwar auch noch ein ziemlicher Noob was Angelscript angeht, habe aber im Ansatz was ähnliches versucht wie du, deshalb versuch ich dir hier mal aus meiner Erfahrung zu helfen.

1. Beide Klassen sollten in der Applikationsschnittstelle mit den in Angelscript benötigten Methoden registriert sein, also

Code: Alles auswählen

//Klassenreferenz registrieren
r = m_engine->RegisterObjectType("Klasse1", sizeof(Klasse1), asOBJ_REF); assert( r >= 0 );

//Methode registrieren (nimmt einen float-wert entgegen)
 r = m_engine->RegisterObjectMethod("Klasse1", "void setValue(float)", asMETHOD(Klasse1,setValue), asCALL_THISCALL); assert( r >= 0 );
Damit das ganze tut ist es wichtig folgende Behaviour-Methoden zu registrieren

Code: Alles auswählen

//REgistering the behaviours
 r = m_engine->RegisterObjectBehaviour("Klasse1",asBEHAVE_ADDREF,"void f()",asMETHOD(Klasse1,addRef),asCALL_THISCALL); assert(r >= 0);
 r = m_engine->RegisterObjectBehaviour("Klasse1",asBEHAVE_RELEASE,"void f()",asMETHOD(Klasse1,release),asCALL_THISCALL); assert(r >= 0);
die aber nur als leere Methoden implementiert sind, wenn du keine neue Instanz der Klasse für die Angelscript-VM erstellen willst. D.h. Wenn du in der Applikation und dem Skript auf die gleiche Instanz zugreifen willst, dann kannst du diese Methoden leer lassen.

Unter der Annahme, dass du eine Funktion im Skript im Stil von

Code: Alles auswählen

void main(Klasse1 @ref)
aufrufen willst, musst du, um die Referenz der Klasse ans Skript zu übergeben, nach dem Aufruf von Prepare auf dem Context(ich nen das im Code VM da es prinzipiell eine VM ist) folgenden Befehl ausführen

Code: Alles auswählen

// Prepare the VM and allocate the required memory
m_vm->Prepare(funcId);

//Always set arguments after Prepare()
m_vm->SetArgObject(0, meineKlasse1Instanz);
Damit wäre ja der erste Teil deiner Wunschliste erfüllt. Prinzipiell denke ich sollte das mit dem zurückgeben der Klasse2 funktionieren, wenn du diese Klasse als Objektreferenz in der Applikationschnittstelle registriert hast. Besonderes Augenmerk musst da wohl auf die Registrierung der Methode legen, die als Ergebnis Klasse2 liefern soll. Da muss ich zugeben, dass ich aucb in der Doku von Angelcode nachschauen müsste (die manchmal etwas komisch verschachtelt und organisiert ist.

Ich hoffe damit etwas weitergeholfen zu haben.

Thoran
<edit> fixed typo</edit>
Zuletzt geändert von Thoran am 11.02.2010, 13:45, insgesamt 1-mal geändert.
Wer Rechtschreibfehler findet, darf diese gerne behalten.
Mein Entwicklertagebuch
Aktuelle Projekte: Universum: Domination (ehemalig AlphaOmega),Universum: Sternenjäger, PixelWars: Highscore-based Top-Down-Spaceshooter
Spieleengine Unreal 5
fkrauthan
Beiträge: 38
Registriert: 28.02.2009, 13:34
Alter Benutzername: fkrauthan
Kontaktdaten:

Re: Anglescript fragen

Beitrag von fkrauthan »

Code: Alles auswählen

r = m_engine->RegisterObjectMethod("Klasse1", "void setValue(float)", asMETHOD(Klasse1,setValue), asCALL_THISCALL); assert( r >= 0 );
Meinst du mit der Zeile ich muss JEDE funktion in meiner Klasse so registrieren?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Anglescript fragen

Beitrag von Schrompf »

fkrauthan hat geschrieben:

Code: Alles auswählen

r = m_engine->RegisterObjectMethod("Klasse1", "void setValue(float)", asMETHOD(Klasse1,setValue), asCALL_THISCALL); assert( r >= 0 );
Meinst du mit der Zeile ich muss JEDE funktion in meiner Klasse so registrieren?
Unbedingt. Woher soll denn Angelscript sonst wissen, welche Funktionen die Klasse hat? Sowas wie Reflection gibt es in C++ nicht. Du meldest die Klasse selbst als Typ an, evtl. Konstruktoren und Destruktor, und natürlich alle Funktionen und Operatoren, die Du im Skript benutzen willst.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
fkrauthan
Beiträge: 38
Registriert: 28.02.2009, 13:34
Alter Benutzername: fkrauthan
Kontaktdaten:

Re: Anglescript fragen

Beitrag von fkrauthan »

Hmm gibt es vllt tricks mit defines oder sowas zu arbeiten um sich die arbeit zu sparren? Wohl eher nicht oder?
Benutzeravatar
Thoran
Establishment
Beiträge: 224
Registriert: 15.05.2009, 12:51
Wohnort: Stuttgart
Kontaktdaten:

Re: Anglescript fragen

Beitrag von Thoran »

Es gibt auf Googlecode einen cpp-wrapper, der dir aus einem C++ header file ein Codefragment erzeugt, das deine komplette Klasse im Applikationsinterface registriert. Ist zumindest ein Ansatz das ganze etwas zu beschleunigen. Muss man aber trotzdem als Präbuild-Ereignis ausführen.

Ein Beispiel aus meiner Techdemo-Spielwiese, in der ich versucht habe ein Geometrieobjekt über ein Skript zu beeinflussen. Ich denke die Funktionen sind selbsterklärend:

Code: Alles auswählen

// Registering the class method
   r = m_engine->RegisterObjectMethod("GameObject", "void translate(float, float, float)", asMETHOD(GameObject,translate), asCALL_THISCALL); assert( r >= 0 );
   r = m_engine->RegisterObjectMethod("GameObject", "void rotate(float, float, float)", asMETHOD(GameObject,rotate), asCALL_THISCALL); assert( r >= 0 );
   r = m_engine->RegisterObjectMethod("GameObject", "float getX()", asMETHOD(GameObject,getX), asCALL_THISCALL); assert( r >= 0 );
   r = m_engine->RegisterObjectMethod("GameObject", "float getY()", asMETHOD(GameObject,getY), asCALL_THISCALL); assert( r >= 0 );
   r = m_engine->RegisterObjectMethod("GameObject", "float getZ()", asMETHOD(GameObject,getZ), asCALL_THISCALL); assert( r >= 0 );
   r = m_engine->RegisterObjectMethod("GameObject", "void setDir(float)", asMETHOD(GameObject,setDir), asCALL_THISCALL); assert( r >= 0 );
und das Angelscript Skript dazu:

Code: Alles auswählen

void main(GameObject @obj)
{
	//Get Z-position of object
	float z = obj.getZ();

        //if -30 on z-axis reached invert direction
	if (z <= -30)
	{
		obj.setDir(1.0f);
	}
	
        //if 18 on z-axis reached invert direction
	if (z >= 18)
	{
		obj.setDir(-1.0f);
	}

        //Translate by a fixed value on the z-axis
	obj.translate(0.0f,0.0f,0.01f);
}
Über die Qualität/den Sinn des Skriptes kannman streiten, aber es dient ja auch nur als demo wie man ein Referenzobjekt beeinflusst.

Thoran
Wer Rechtschreibfehler findet, darf diese gerne behalten.
Mein Entwicklertagebuch
Aktuelle Projekte: Universum: Domination (ehemalig AlphaOmega),Universum: Sternenjäger, PixelWars: Highscore-based Top-Down-Spaceshooter
Spieleengine Unreal 5
fkrauthan
Beiträge: 38
Registriert: 28.02.2009, 13:34
Alter Benutzername: fkrauthan
Kontaktdaten:

Re: Anglescript fragen

Beitrag von fkrauthan »

Hmm ok. Naja ich hab mir gerade nen eigenen Script geschrieben, der das ganze umwandelt. Allerdings mit einer grundlegenden verbesserung zu dem cpp-wrapper. Dadurch kann man bei meinem Script durch spezielle kommentare sagen welche Funktionen nach ausen hin offen sind. (Also welche der Parser alles bei Angelscript registrieren soll.) Ein paar kleine schwächen hat mein parser allerdings. Aber die sind bei meinen projekten eh nicht vorhanden.
Antworten