Advertisement

Problem saving/loading bytecodes (angelscript bug?)

Started by May 19, 2007 04:11 PM
32 comments, last by WitchLord 17 years, 4 months ago
Hmm, just adding those lines to the example that reproduced the previous problem didn't reproduce the new problem. I'll try adding the rest of your example, to see if that may reproduce this new problem.

In the meantime: Is Shot an Actor as well? Or is it an application registered class?





AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Thanks for the hard work in this splendid script engine! :)

Yes, Shot is an Actor like the others.
=====================================Regards,Juan Pablo (McKrackeN) Bettini Psychoban Official Site:http://www.psychoban.comPsychoban on iTunes App Store:http://itunes.apple.com/us/app/psychoban/id378692853?mt=8
Advertisement
Please let me know how you've registered the classes involved, i.e. Sprite, Animation, g_checkCollision, g_AsteroidMgr.

I've not been able to reproduce the problem yet, even though I've added practically all of your shown script code. Maybe it has something to do with those other classes.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

The Sprite and Animation are C++ classes registered in the engine. The Sprite class in particular inherits from Shape that inherits from Entity2D and so on. I register them like this:

bool Shape::RegisterShape(char *className) {	char _className[100];	if (className != NULL) {		strcpy_s(_className, 100, className);	} else {		strcpy_s(_className, 100, "Shape");		if (ScriptMgr::RegisterObjectType(_className, sizeof(Shape), asOBJ_CLASS | asOBJ_CLASS_CONSTRUCTOR) < 0)			return false;		if (ScriptMgr::RegisterObjectBehaviour(_className, asBEHAVE_CONSTRUCT,"void f()", asFUNCTION(Constructor), asCALL_CDECL_OBJLAST) < 0)			return false;		if (ScriptMgr::RegisterObjectBehaviour(_className, asBEHAVE_DESTRUCT,"void f()", asFUNCTION(Destructor), asCALL_CDECL_OBJLAST) < 0)			return false;		if (ScriptMgr::RegisterObjectMethod(_className, "void Draw()", asMETHODPR(Shape, Draw, (void), void), asCALL_THISCALL) < 0)			return false;		if (ScriptMgr::RegisterObjectMethod(_className, "void Update(float)", asMETHODPR(Shape, Update, (float), void), asCALL_THISCALL) < 0)			return false;		//-----------------------------------------		// Arreglos de Shapes		//-----------------------------------------		// Register std::vector<int>		if (!RegisterVector<Shape>("Shape[]", "Shape", (asIScriptEngine *)ScriptMgr::GetEngine()))			return false;	}	if (!Entity2D::RegisterEntity2D(_className))		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetShape(int)", asMETHODPR(Shape, SetShape, (int), void), asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetColor(uint)",asMETHOD(Shape, SetColor),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetColorPerVertex(uint,uint,uint)",asMETHODPR(Shape, SetColorPerVertex, (DWORD,DWORD,DWORD), void),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetColorPerVertex(uint,uint,uint,uint)",asMETHODPR(Shape, SetColorPerVertex, (DWORD,DWORD,DWORD,DWORD), void),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetRadius(float)",asMETHOD(Shape, SetRadius),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetSegmentsCount(int)",asMETHOD(Shape, SetSegmentsCount),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "bool IsColliding(Shape &in)",asMETHOD(Entity2D, IsColliding),asCALL_THISCALL) < 0)		return false;	return true;}bool Sprite::RegisterSprite(char *className) {	char _className[100];	if (className != NULL) {		strcpy_s(_className, 100, className);	} else {		strcpy_s(_className, 100, "Sprite");		if (ScriptMgr::RegisterObjectType(_className, sizeof(Sprite), asOBJ_CLASS | asOBJ_CLASS_CONSTRUCTOR) < 0)			return false;		if (ScriptMgr::RegisterObjectBehaviour(_className, asBEHAVE_CONSTRUCT,"void f()", asFUNCTION(Constructor), asCALL_CDECL_OBJLAST) < 0)			return false;		if (ScriptMgr::RegisterObjectBehaviour(_className, asBEHAVE_DESTRUCT,"void f()", asFUNCTION(Destructor), asCALL_CDECL_OBJLAST) < 0)			return false;		if (ScriptMgr::RegisterObjectMethod(_className, "void Draw()", asMETHODPR(Sprite, Draw, (void), void), asCALL_THISCALL) < 0)			return false;		if (ScriptMgr::RegisterObjectMethod(_className, "void Update(float)", asMETHODPR(Sprite, Update, (float), void), asCALL_THISCALL) < 0)			return false;		//-----------------------------------------		// Arreglos de Sprites		//-----------------------------------------		// Register std::vector<int>		if (!RegisterVector<Sprite>("Sprite[]", "Sprite", (asIScriptEngine *)ScriptMgr::GetEngine()))			return false;	}	if (!Shape::RegisterShape(_className))		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "Animation@ GetAnimation()",asMETHOD(Sprite, GetAnimation),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetAnimation(Animation &in)",asMETHODPR(Sprite, SetAnimation, (Animation*), void),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "void SetFrame(int)",asMETHOD(Sprite, SetFrame),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "int GetCurrentFrame()",asMETHOD(Sprite, GetCurrentFrame),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "bool IsAnimationRunning()",asMETHOD(Sprite, IsAnimationRunning),asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "bool Load(string &in)", asMETHODPR(Sprite, Load, (const string&), bool), asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "bool Unload()", asMETHOD(Sprite, Unload), asCALL_THISCALL) < 0)		return false;	if (ScriptMgr::RegisterObjectMethod(_className, "bool IsColliding(Sprite&in)",asMETHOD(Entity2D, IsColliding),asCALL_THISCALL) < 0)		return false;	return true;


And so on. So you register the methods once per class just by calling the register method.

The others (g_checkCollision and g_asteroidMgr) are instances from script declared classes.

class CheckCollision {	Actor@[] _list1;	Actor@[] _list2;	int _lastList1;	int _lastList2;	bool Initialize() {		_list1.resize(COLLISION_MAX_ENTITIES);		_list2.resize(COLLISION_MAX_ENTITIES);		_lastList1 = 0;		_lastList2 = 0;		return true;	}	bool Register(Actor@ entity, int list){		switch (list) {			case 1:				if (_lastList1 < COLLISION_MAX_ENTITIES) {					@_list1[_lastList1] = @entity;					_lastList1++;					return true;				}				break;			case 2:				if (_lastList2 < COLLISION_MAX_ENTITIES) {					@_list2[_lastList2] = @entity;					_lastList2++;					return true;				}				break;		}		return false;	}	bool Unregister(Actor@ entity, int list) {		int i=0;		switch (list) {			case 1:				while (i<_lastList1 && @_list1 != @entity)					i++;				if (@_list1 == @entity) {					_lastList1--;					@_list1 = @_list1[_lastList1];					return true;				}				break;			case 2:				while (i<_lastList2 && @_list2 != @entity)					i++;				if (@_list2 == @entity) {					_lastList2--;					@_list2 = @_list2[_lastList2];					return true;				}				break;		}		return false;	}	void Clear() {		_lastList1 = 0;		_lastList2 = 0;		//_list1.resize(0);		//_list2.resize(0);	}	void Check() {		float x1;		float y1;		float r1;		float x2;		float y2;		float r2;		for (int i=0; i < _lastList1; i++) {			x1 = _list1.GetPosX();			y1 = _list1.GetPosY();			r1 = _list1.GetCollisionRadius();			for (int j=0; j < _lastList2; j++) {				x2 = _list2[j].GetPosX();				y2 = _list2[j].GetPosY();				r2 = _list2[j].GetCollisionRadius();				if (_list1.GetCheckCollision() && _list2[j].GetCheckCollision()) {					if ((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) <= (r1+r2)*(r1+r2)) {						_list1.OnCollide(_list2[j]);						_list2[j].OnCollide(_list1);					}				}			}		}	}		}class AsteroidMgr {	Asteroid[] _asteroids;	void Clear() {		for (int i=0; i < _asteroids.length(); i++) {			_asteroids.Shutdown();		}	 		//_asteroids.resize(0);	}	bool Initialize(int asteroidCount) {		if (asteroidCount <= 0) 			return false;			_asteroids.resize(asteroidCount);				for (int i=0; i < _asteroids.length(); i++) {			if (!_asteroids.Initialize())				return false;			_asteroids._sprite.SetVisible(true);			_asteroids._sprite.SetCheckCollision(true);		}		return true;	}	void Update(float dt) {		for (int i=0; i < _asteroids.length(); i++) {			_asteroids.Update(dt);		}	}	void Draw() {		for (int i=0; i < _asteroids.length(); i++) {			_asteroids.Draw();		}	}	void Shutdown() {		for (int i=0; i < _asteroids.length(); i++) {			_asteroids.Shutdown();		}		//_asteroids.resize(0);	}}AsteroidMgr g_AsteroidMgr;CheckCollision g_checkCollision;


Here is the Shot class:

const float SHOT_SPEED	= 0.6f;class Shot : Actor {	Sprite _sprite;	float _vx;	float _vy;	float GetPosX() { return _sprite.GetPosX(); }	float GetPosY() { return _sprite.GetPosY(); }	float GetCollisionRadius() { return _sprite.GetCollisionRadius(); }	bool GetCheckCollision() { return _sprite.GetCheckCollision(); }	void SetVisible(bool visible) {		_sprite.SetVisible(visible);	}	bool GetVisible() {		return _sprite.GetVisible();	}	string GetName() {		return _sprite.GetName();	}	bool Initialize() {		if (!_sprite.Load("data/graphics/shot.spr"))			return false;		_vx = 0;		_vy = 0;		_sprite.SetVisible(false);		_sprite.SetName("shot");		_sprite.SetCheckCollision(false);		_sprite.SetCollisionRadius(5);		if (!g_checkCollision.Register(this, 1))			return false;		return true;		}	void Shoot(float fromX, float fromY, float angle) {		_sprite.SetPos(fromX, fromY);		_sprite.SetAngleZ(angle);		_vx = SHOT_SPEED*cos(angle);		_vy = SHOT_SPEED*sin(angle);		_sprite.SetVisible(true);		_sprite.SetCheckCollision(true);	}	void Update(float dt) {		_sprite.Update(dt);		float x = _sprite.GetPosX();		float y = _sprite.GetPosY();		int w = g_graphics.GetViewportWidth()/2;		int h = g_graphics.GetViewportHeight()/2;		x += _vx * dt;		y += _vy * dt;		// Verificamos si la posición		// atraviesa alguno de los extremos		// de la pantalla		if (abs(x) > w || abs(y) > h) {			_sprite.SetVisible(false);			_sprite.SetCheckCollision(false);		}		_sprite.SetPos(x, y);	}	void Draw() {		_sprite.Draw();	}	void Shutdown() {		_sprite.Unload();	}	void OnCollide(Actor@+ actor) {		_sprite.SetVisible(false);		_sprite.SetCheckCollision(false);		}}


[edit]
I've made a mistake before, the problem is in the line:
@_shots = @shot;

[/edit]

=====================================Regards,Juan Pablo (McKrackeN) Bettini Psychoban Official Site:http://www.psychoban.comPsychoban on iTunes App Store:http://itunes.apple.com/us/app/psychoban/id378692853?mt=8
I've been able to reproduce the problem with this added information. I still haven't pinpointed the exact problem though, but now it's only a matter of time.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Great!!! Thank you!!! :)
=====================================Regards,Juan Pablo (McKrackeN) Bettini Psychoban Official Site:http://www.psychoban.comPsychoban on iTunes App Store:http://itunes.apple.com/us/app/psychoban/id378692853?mt=8
Advertisement
I actually fixed the bug yesterday, but I haven't had the time to check-in the code fix yet. Hopefully I'll be able to do so tonight when I get home.

The problem is related to the last bug fix, about the out-of-order declarations. This time it for the script arrays. When loading the _list1 property of CheckCollision, the Actor type has been defined, but not fully initialized yet. This lead to the Actor@[] type being initialized incorrectly, thus causing the bad behaviour in the script array object.

There's no work around for this problem. You'll have to wait for the checkin to get this working.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Fantastic!!! Thank you again... and again... and so on :P

When I try it, I let you know if it works well. :)
=====================================Regards,Juan Pablo (McKrackeN) Bettini Psychoban Official Site:http://www.psychoban.comPsychoban on iTunes App Store:http://itunes.apple.com/us/app/psychoban/id378692853?mt=8
I've checked in the code now (revision 165).

Let me know if you have more problems.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

It works perfectly!! Thanks!!!!!!!
=====================================Regards,Juan Pablo (McKrackeN) Bettini Psychoban Official Site:http://www.psychoban.comPsychoban on iTunes App Store:http://itunes.apple.com/us/app/psychoban/id378692853?mt=8

This topic is closed to new replies.

Advertisement