Jump to content
  • Advertisement
Sign in to follow this  
Quillraven

Angelscript class inheritance question

This topic is 2596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi,

i hope this is the right forum for this kind of questions. first of all i'm new to angelscript so pls don't blame me for not knowing everything.

i wanted to use angelscript for the following:
- in my c++ project i want to define interfaces like a unit in a game or a gamestate
- in .as files i want to define the specific implementations of the interfaces like a goblin unit or a mainmenu gamestate

however i couldn't find a good tutorial that is up to date to help me developing this idea.

i know how to initialize the scriptengine and how to execute a function of a script and how to execute a c++ function by a script. i also read something about registering classes and methods (f.e. here: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_adv_class_hierarchy.html).

so what exactly do i need to get the following to work:
- i have one class that is used for rendering something to the screen
- i have an IGameState interface that defines four methods: init, exit, update and render
- i have a MainMenu.as file that defines the specific MainMenu gamestate that is inherited from IGameState

do i only need to register the render method of the renderclass if the mainmenu class only calls the render method?
do i need to register the entire IGameState interface althoug the methods aren't implemented?
how do i register the mainmenu class? i defined a register function in the mainmenu.as script that registers the mainmenu class but i'm not sure if this is the correct way.
how am i able to call the render method of the mainmenu class?

if anyone has a short tutorial code or sthg, that would be really helpful.

what i've got so far (some code snippets):
renderclass - http://codepad.org/TTXSdvu8
MainMenu.as - http://codepad.org/btqC79sk
IGameState - http://codepad.org/4nNp6Ew3


sorry for my bad english, i hope you understand what i mean.

Share this post


Link to post
Share on other sites
Advertisement
You only need to register what the scripts are going to access. If the script isn't supposed to call a method or have access to a type, then don't register it.

I suggest you take a close look at the game sample that comes with the SDK. Although it doesn't have much of a graphic interface, it should give you a good idea of how you can expose a game interface that will allow you to write scripts that control the game entities.

Many of the questions you may have are probably answered by that sample. Once you've understood how the game sample works, then let us know what further doubts you may have.


Regards,
Andreas

Share this post


Link to post
Share on other sites
thx for the hing with the game sample. however the game doesn't seem to work? i compiled it and started it, the gamefield is created but moving the player by typing u,l,r,d or up,down,left... doesn't do anything so i'm not quite sure if i should study this tutorial if it doesn't seem to work.

another question: the player and zombie are including an icontroller interface, that is register in the c++ code but there is no icontroller interface defined neither in the scripts nor in the c++ sourcecode. what is the point of this interface then if it doesn't exist oO

Share this post


Link to post
Share on other sites
You're probably not running the game from the bin directory, so it doesn't find the script files. That's why nothing happens when you type the user actions.

I'll have to modify this to show an error message if this happens.




The IController interface is empty, and is only used as an indicator to tell the game engine which class is implementing the entity controller. You're not required to do it like this, you could also indicate the class by it's name, or rely on the script to only include one class declaration.


See the code comments where the interface is registered:


// The game engine will determine the class that represents the controller
// by checking if the class implements the IController interface. No methods
// are registered for this interface, as the script shouldn't be required to
// implement the methods. This will allow the game engine to avoid calling
// methods that doesn't do anything, thus improving performance.
r = engine->RegisterInterface("IController"); assert( r >= 0 );









Share this post


Link to post
Share on other sites
sry, but i was still not able to get it to work. i wonder if it's even possible with angelscript?

i went through the game sample, but in my case it doesn't really help.
first of all i don't have an interface. i have more of an abstract class that i try to use as base class for scriptclasses.
i wrote a simple example to experiment around with angelscript.

i want to define the base class in c++, like i did it in my testscenario:

class Unit
{
private:
int _refCount;

protected:
std::string _name;
int _life;

public:
Unit( const std::string& name )
{
_refCount = 1;
_name = name;
}
static Unit* asFactory( const std::string& name )
{
return new Unit( name );
}
void AddRef()
{
_refCount++;
}
void Release()
{
_refCount--;
if( _refCount <= 0 )
delete this;
}
virtual ~Unit()
{

}
void setLife( int newLife )
{
_life = newLife;
}
virtual void print()
{
printText( _name.append( "\n\tLeben: " + _life ) );
}
};


this should be the base class for units. i then want to inherit from that class in scriptfiles f.e. class Soldier : Unit to "create" a specific soldier unit.

however when i try to do that, i get a builderror when trying to build the script:


class Frosch : Unit
{
Frosch()
{
super("Frog");
}

void print()
{
array<string> arr = {"Froschdaten:", "Name: " + this._name, "Leben: " + this._life};
string data = join(arr, "\n");

printText( data );
}
}


i get the following errors:


Default/frog.as (1, 16) : ERR : Can't inherit from 'Unit'
Assertion failed: r>=0, file ../Source/main.cpp, line 132

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Default/frog.as (3, 2) : INFO : Compiling Frosch::Frosch()
Default/frog.as (5, 3) : ERR : No matching signatures to 'Frosch::super(string)'
Default/frog.as (8, 2) : INFO : Compiling void Frosch::print()
Default/frog.as (10, 55) : ERR : '_name' is not a member of 'Frosch'
Default/frog.as (10, 79) : ERR : '_life' is not a member of 'Frosch'


so it seems like it's impossible to inherit from unit although i register it before i try to build the script? what am i missing? what am i doing wrong? :(



r = AS_ENGINE->RegisterObjectType( "Unit", sizeof(Unit), asOBJ_REF );
assert( r>=0 );
/*r = AS_ENGINE->RegisterObjectProperty( "Unit", "string _name", offsetof(Unit,_name) );
assert( r>=0 );
r = AS_ENGINE->RegisterObjectProperty( "Unit", "int _life", offsetof(Unit,_life) );
assert( r>=0 );*/
r = AS_ENGINE->RegisterObjectBehaviour(
"Unit",
asBEHAVE_FACTORY,
"Unit@ Unit(const string &in)",
asFUNCTIONPR(Unit::asFactory,(const std::string&),Unit*),
asCALL_STDCALL );
assert( r>=0 );
r = AS_ENGINE->RegisterObjectBehaviour( "Unit", asBEHAVE_ADDREF, "void f()", asMETHOD(Unit,AddRef), asCALL_THISCALL );
assert( r >= 0 );
r = AS_ENGINE->RegisterObjectBehaviour( "Unit", asBEHAVE_RELEASE, "void f()", asMETHOD(Unit,Release), asCALL_THISCALL );
assert( r >= 0 );
r = AS_ENGINE->RegisterObjectMethod( "Unit", "void setLife(int)", asMETHOD(Unit,setLife), asCALL_THISCALL );
assert( r>= 0 );
r = AS_ENGINE->RegisterObjectMethod( "Unit", "void print()", asMETHOD(Unit,print), asCALL_THISCALL );
assert( r>= 0 );

// ....


CScriptBuilder builder;
r = builder.StartNewModule( AS_ENGINE, "Frosch" );
assert( r>=0 );
r = builder.AddSectionFromFile( "Default/frog.as" );
assert( r>=0 );
r = builder.BuildModule();
assert( r>=0 );

Share this post


Link to post
Share on other sites
No, it's not possible for a script class to inherit from an application registered class. The implementation is fundamentally different and wouldn't work.

However, you can 'emulate' the inheritance by wrapping the application registered class in a script class, and then inherit from that one instead.

Here's a forum thread that describes how that can be done: http://www.gamedev.net/topic/535837-application-registered-classes/

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!