Jump to content
  • Advertisement
Sign in to follow this  
Fayte

Passing a value into a bound class.

This topic is 2115 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

Ok here's the deal,

I have an Image class with a draw function like this:

void Img::Draw(SDL_Surface* surface) {
SDL_Rect offset;
offset.x = X;
offset.y = Y;
SDL_BlitSurface(imgSurface, NULL, surface, &offset);
}


I would like to be able to do this in the script:

Image img;

img.x = 0;
img.y = 0;

img.Draw();


But I need to pass the screen Surface to the draw function I don't want my scripters to have to do img.Draw(GetSurface()); I would like this to be handled through the C++ backend code is there a way that everytime img.Draw() is called in script I can pass the SDL_Surface into the C++ method?

If you need this explained better ask away its 12 A.M. here tongue.png might not have explained it the best. Edited by Fayte

Share this post


Link to post
Share on other sites
Advertisement

how about you also have this draw function


void Img::Draw() {
Draw(GetSurface());
}



Well I thought that at first too, but the thing is GetSurface(); is in my engine class which has an instance that would need to be passed but I don't know if I can pass the instance into the Image class every time a new one is created in Angelscript. Sorry rather new to Angelscript sad.png

Share this post


Link to post
Share on other sites
then i just dont understand why you cant create a second function in you Img class.

class Img
{
void Img::Draw(SDL_Surface* surface)
{
SDL_Rect offset;
offset.x = X;
offset.y = Y;
SDL_BlitSurface(imgSurface, NULL, surface, &offset);
}

void Img::Draw()
{
Draw(GetSurface());
}
}

register Img::Draw() to script.
like this

r = engine->RegisterObjectMethod("Image", "void Draw()", asMETHODPR(Image, Draw, (void), void), asCALL_THISCALL);


surely you have access to GetSurface() function in C++. ( or engine->GetSurface() )

Share this post


Link to post
Share on other sites

then i just dont understand why you cant create a second function in you Img class.

class Img
{
void Img::Draw(SDL_Surface* surface)
{
SDL_Rect offset;
offset.x = X;
offset.y = Y;
SDL_BlitSurface(imgSurface, NULL, surface, &offset);
}

void Img::Draw()
{
Draw(GetSurface());
}
}

register Img::Draw() to script.
like this

r = engine->RegisterObjectMethod("Image", "void Draw()", asMETHODPR(Image, Draw, (void), void), asCALL_THISCALL);


surely you have access to GetSurface() function in C++. ( or engine->GetSurface() )

You are quite right but I cant pass my engine variable into a c++ class that's not instanced yet can I? Sorry for being newbish like I said I'm new to angelscript. But I don't know how to pass in GetSurface() into my Img class. Without first saying Image img = new Image(engine); on my C++ side.

Share this post


Link to post
Share on other sites
your problem is pretty much a c++ pointer ownership issue.

So what is this mystical "engine" class would you show me?

Share this post


Link to post
Share on other sites
Here's how I give my classes access to the main engine class:

When I set up the script engine, I pass the address of my engine class instance in as userdata (a void pointer):


engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetUserData(&myGameEngine);


Then, in my class constructors that need a pointer to the engine (to access window drawing, content management, etc.), I do this:


asIScriptContext* context = NULL;
asIScriptEngine* engine = NULL;
context = asGetActiveContext(); // Get the currently executing angelscript context
if ((context = asGetActiveContext()) != NULL && (engine = context->GetEngine()) != NULL)
{
// owner is a member pointer to the engine
owner = reinterpret_cast<Engine*>(engine->GetUserData());
}


Hopefully that helps. Edited by Jake Albano

Share this post


Link to post
Share on other sites

Here's how I give my classes access to the main engine class:

When I set up the script engine, I pass the address of my engine class instance in as userdata (a void pointer):


engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetUserData(&myGameEngine);


Then, in my class constructors that need a pointer to the engine (to access window drawing, content management, etc.), I do this:


asIScriptContext* context = NULL;
asIScriptEngine* engine = NULL;
context = asGetActiveContext(); // Get the currently executing angelscript context
if ((context = asGetActiveContext()) != NULL && (engine = context->GetEngine()) != NULL)
{
// owner is a member pointer to the engine
owner = reinterpret_cast<Engine*>(engine->GetUserData());
}


Hopefully that helps.


Gonna try that but here is my engine class


#include "Engine.h"
#include <windows.h> // For the WaitMessage() function.
#include "Scripting/ScriptManager.h"
using namespace Ogre;
/** Default constructor. **/
AffinityEngine::AffinityEngine() {
m_lLastTick = 0;
m_iWidth = 1024;
m_iHeight = 768;
m_czTitle = 0;
m_pScreen = 0;
m_iFPSTickCounter = 0;
m_iFPSCounter = 0;
m_iCurrentFPS = 0;
m_bMinimized = false;
}
/** Destructor. **/
AffinityEngine::~AffinityEngine() {
SDL_Quit();
}
/** Sets the height and width of the window.
@param iWidth The width of the window
@param iHeight The height of the window
**/
void AffinityEngine::SetSize(const int& iWidth, const int& iHeight) {
m_iWidth = iWidth;
m_iHeight = iHeight;
if(m_vmVideoMode == VideoMode_3D) {
m_pScreen = SDL_SetVideoMode( iWidth, iHeight, 0, SDL_OPENGL );
} else if(m_vmVideoMode == VideoMode_2D) {
m_pScreen = SDL_SetVideoMode( iWidth, iHeight, 0, SDL_SWSURFACE );
}
}
/** Initialize SDL, the window and the additional data. **/
void AffinityEngine::Init(VideoMode videoMode) {
printf("Engine Initialing.\n");
// Register SDL_Quit to be called at exit; makes sure things are cleaned up when we quit.
atexit( SDL_Quit );
// Initialize SDL's subsystems - in this case, only video.
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
fprintf( stderr, "Unable to init SDL: %s\n", SDL_GetError() );
exit( 1 );
}
SetTitle("Affinity Engine");
m_vmVideoMode = videoMode;
// Attempt to create a window with the specified height and width.
SetSize(m_iWidth, m_iHeight);
if(videoMode == VideoMode_3D){
m_rRoot = new Root("plugins_d.cfg", "ogre.cfg", "AffinityEngine.log");
m_rRoot->restoreConfig();
m_rRoot->initialise(false);
NameValuePairList misc;
#ifdef _WIN32
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWMInfo(&wmInfo);

size_t winHandle = reinterpret_cast<size_t>(wmInfo.window);
size_t winGlContext = reinterpret_cast<size_t>(wmInfo.hglrc);

misc["externalWindowHandle"] = StringConverter::toString(winHandle);
misc["externalGLContext"] = StringConverter::toString(winGlContext);
#else
misc["currentGLContext"] = String("True");
#endif
m_rwRenderWindow = m_rRoot->createRenderWindow("MainRenderWindow", 1024, 768, false, &misc);
m_rwRenderWindow->setVisible(true);
printf("Initialized 3D Rendering.\n");
} else {
printf("Initialized 2D Rendering.\n");
}
// If we fail, return error.
if ( m_pScreen == NULL ) {
fprintf( stderr, "Unable to set up video: %s\n", SDL_GetError() );
exit( 1 );
}
printf("Engine Initialized.\n");
AdditionalInit();
}
/** The main loop. **/
void AffinityEngine::Start() {
printf("Engine Started\n");
m_lLastTick = SDL_GetTicks();
m_bQuit = false;
m_smScriptManager = new ScriptManager("../Data/Scripts", this);
m_smScriptManager->Init();
// Main loop: loop forever.
while ( !m_bQuit ) {
// Handle mouse and keyboard input
HandleInput();
if ( m_bMinimized ) {
// Release some system resources if the app. is minimized.
WaitMessage(); // pause the application until focus in regained
} else {
// Do some thinking
DoLogic();
// Render stuff
DoRender();
}
}
End();
}
/** Handles all controller inputs.
@remark This function is called once per frame.
**/
void AffinityEngine::HandleInput() {
// Poll for events, and handle the ones we care about.
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_KEYDOWN:
// If escape is pressed set the Quit-flag
/*if (event.key.keysym.sym == SDLK_ESCAPE){
m_bQuit = true;
break;
}*/
m_smScriptManager->e_imInputMgr->InjectKeyboard(event.key.keysym.sym, InputState::Down);
KeyDown(event.key.keysym.sym);
break;
case SDL_KEYUP:
m_smScriptManager->e_imInputMgr->InjectKeyboard(event.key.keysym.sym, InputState::Up);
KeyUp(event.key.keysym.sym);
break;
case SDL_QUIT:
m_bQuit = true;
break;
case SDL_MOUSEMOTION:
m_smScriptManager->e_imInputMgr->InjectMouse(event.motion.x, event.motion.y, event.button.button);
MouseMoved(event.button.button, event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel);
break;
case SDL_MOUSEBUTTONUP:
m_smScriptManager->e_imInputMgr->InjectMouse(event.motion.x, event.motion.y, event.button.button);
MouseButtonUp(event.button.button, event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel);
break;
case SDL_MOUSEBUTTONDOWN:
m_smScriptManager->e_imInputMgr->InjectMouse(event.motion.x, event.motion.y, event.button.button);
MouseButtonDown(event.button.button, event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel);
break;
case SDL_ACTIVEEVENT:
if ( event.active.state & SDL_APPACTIVE ) {
if ( event.active.gain ) {
m_bMinimized = false;
WindowActive();
} else {
m_bMinimized = true;
WindowInactive();
}
}
break;
} // switch
} // while (handling input)
}
/** Handles the updating routine. **/
void AffinityEngine::DoLogic() {
long iElapsedTicks = SDL_GetTicks() - m_lLastTick;
m_lLastTick = SDL_GetTicks();
m_smScriptManager->ParseScripts();
Logic( iElapsedTicks );
m_smScriptManager->Update();
m_iFPSTickCounter += iElapsedTicks;
}
/** Handles the rendering and FPS calculations. **/
void AffinityEngine::DoRender() {
++m_iFPSCounter;
if ( m_iFPSTickCounter >= 1000 ) {
m_iCurrentFPS = m_iFPSCounter;
m_iFPSCounter = 0;
m_iFPSTickCounter = 0;
}
if(m_vmVideoMode == VideoMode_2D) {
SDL_FillRect( m_pScreen, 0, SDL_MapRGB( m_pScreen->format, 0, 0, 0 ) );
// Lock surface if needed
if ( SDL_MUSTLOCK( m_pScreen ) )
if ( SDL_LockSurface( m_pScreen ) < 0 )
return;
Render( GetSurface() );
m_smScriptManager->Draw();
// Unlock if needed
if ( SDL_MUSTLOCK( m_pScreen ) )
SDL_UnlockSurface( m_pScreen );
// Tell SDL to update the whole gScreen
SDL_Flip( m_pScreen );
}else{
m_rRoot->renderOneFrame();
SDL_GL_SwapBuffers();
}
}
/** Sets the title of the window
@param czTitle A character array that contains the text that the window title should be set to.
**/
void AffinityEngine::SetTitle(std::string czTitle) {
m_czTitle = czTitle.c_str();
SDL_WM_SetCaption( czTitle.c_str(), 0 );
}
/** Retrieve the title of the application window.
@return The last set windows title as a character array.
@remark Only the last set title is returned. If another application has changed the window title, then that title won't be returned.
**/
const char* AffinityEngine::GetTitle() {
return m_czTitle;
}
/** Retrieve the main screen surface.
@return A pointer to the SDL_Surface surface
@remark The surface is not validated internally.
**/
SDL_Surface* AffinityEngine::GetSurface() {
return m_pScreen;
}
/** Get the current FPS.
@return The number of drawn frames in the last second.
@remark The FPS is only updated once each second.
**/
int AffinityEngine::GetFPS() {
return m_iCurrentFPS;
}
void AffinityEngine::Shutdown() {
m_bQuit = true;
}
ScriptManager* AffinityEngine::GetScriptManager() {
return m_smScriptManager;
}


Ok while making those changes I got this error:

Engine Initialing.
Initialized 2D Rendering.
Engine Initialized.
Engine Started
(0, 0) : ERR : Failed in call to function 'RegisterObjectBehaviour' with 'Imag
e' and 'ref@ f()' (Code: -10)


from this line


r = e_seScriptEngine->RegisterObjectBehaviour("Image", asBEHAVE_FACTORY, "ref@ f()", asFUNCTION(Img_Factory), asCALL_CDECL); assert(r >= 0);


and here is the function:


static Img* Img_Factory() {
return new Img();
}
Edited by Fayte

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!