Page 1 of 3

A Lua in game console.

Posted: Tue Sep 29, 2009 9:04 am
by merlinblack
Hey everyone,

I've just finished writing and pasting my code into this http://www.ogre3d.org/wiki/index.php/LuaConsole

Have a look, and get back to me on any questions or perhaps edit out any spelling mistakes I've missed or whatever.

I think the code needs more comments perhaps.

I'm now off in search of food. :P

Cheers! 8)

Nigel

Re: A Lua in game console.

Posted: Tue Sep 29, 2009 5:50 pm
by xavier
Right on, I expect this will be well-received. :)

Blinkin curse ..... or

Posted: Wed Oct 07, 2009 10:27 am
by merlinblack
I've added some simple code for a blinking cursor to the console class. Works quite well except when using a proportional font it looks a little strange when the cursor is in the middle of the text, as the line length 'blinks' too. Nothing too serious, but it's a great improvement for so little code added. :D

Re: A Lua in game console.

Posted: Wed Oct 07, 2009 7:08 pm
by PJani
I have python interpreter in ingame console(). :D Works like hell.

Re: A Lua in game console.

Posted: Thu Oct 08, 2009 10:50 am
by merlinblack
Yeah Python rocks. :D However I've only used it standalone so far.

Re: A Lua in game console.

Posted: Mon Nov 23, 2009 2:02 pm
by gershon
kodus! this thing rocks, using luabind (followed http://www.codeproject.com/KB/graphics/ ... gre3d.aspx) gives sweet runtime scripting :D

Image

Re: A Lua in game console.

Posted: Mon Nov 23, 2009 10:08 pm
by merlinblack
gershon wrote:kodus! this thing rocks, using luabind (followed http://www.codeproject.com/KB/graphics/ ... gre3d.aspx) gives sweet runtime scripting :D

Image
Now that's cool. I wrote that article too! I'm glad it's helping people out! I'm presently playing around with a cut down gui system, driven by Lua. So far I have two in one program. One is like a simpler version of BetaGUI bound to Lua, and the other is a one class design, where you make more specialized classes/widgets in Lua. I'm comparing the two approaches. The two represent different placement of the script/c++ divide. All this made much much easier by having the console there.

I finding some 'interesting' things out about Luabind at the same time. :roll: But I have to say, the latest one (0.9.1) totally rocks.

Nigel

Re: A Lua in game console.

Posted: Tue Jan 19, 2010 8:32 am
by jacmoe
Very nice starting point for a console! :)

I have a small fix:

Code: Select all

        case OIS::KC_UP:
			if(!history.empty())
			{
				if( history_line == history.begin() )
					history_line = history.end();
				history_line--;
				editline.setText( *history_line );
				textChanged = true;
			}
			break;
 
        case OIS::KC_DOWN:
			if(!history.empty())
			{
				history_line++;
				if( history_line == history.end() )
					history_line = history.begin();
				editline.setText( *history_line );
				textChanged = true;
			}
If we're not checking for an empty history, it will crash when it is, ie when pressing UP in the console when nothing has been entered yet. :)

Re: A Lua in game console.

Posted: Wed Jan 20, 2010 6:15 am
by merlinblack
Cool! I'll update the wiki and my own code. Thanks!

Re: A Lua in game console.

Posted: Fri Jan 22, 2010 3:01 pm
by jacmoe
I made a console using Angelscript based on this. :)
Will make a wiki article rsn. Thanks a lot!

Re: A Lua in game console.

Posted: Sat Jan 23, 2010 9:30 pm
by merlinblack
You didn't go for bash? :P
Was it just a case of writing a new interpreter class? I wrote it with that in mind. I just noticed a couple of things to tidy up in the code that's on the wiki, compared to what I now use. I'll have to have an update session. It's great to see it being useful. :)

Re: A Lua in game console.

Posted: Sat Jan 23, 2010 10:15 pm
by jacmoe
I think so, I'll check. But I am fairly sure I just hacked a new interpreter from the old one. :)
I might have made some adjustments to allow me to use it with the new OgreBites trays. But, I'll check.
A good starting point.

I chose Angelscript because it's the by far easiest scripting library to bind. :)


This is my console script functions so far:

Code: Select all

	asIScriptEngine* engine = AngelScriptInterpreter::getSingletonPtr()->getInterpreter();
	engine->RegisterObjectType("TerrainTest", 0, asOBJ_REF | asOBJ_NOHANDLE);
	engine->RegisterObjectMethod("TerrainTest", "void quit()", asMETHOD(TerrainTest, quit), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void saveCampos()", asMETHOD(TerrainTest, saveCampos), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void restoreCampos()", asMETHOD(TerrainTest, restoreCampos), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void setCampos(float, float, float)", asMETHOD(TerrainTest, setCampos), asCALL_THISCALL);
	engine->RegisterObjectMethod("TerrainTest", "void saveTerrain()", asMETHOD(TerrainTest, saveTerrain), asCALL_THISCALL);

	// Register the singleton's address that the script will use to access it
	engine->RegisterGlobalProperty("TerrainTest app", this);
Allows me to call 'app.quit()', 'app.saveTerrain()', etc. from the console.
That's pure Angelscript, no wrapper or anything.
Even I can figure out how to use it. :P

I plan to implement auto-complete, which is fairly simple to do using Angelscript. Just iterate the functions on the 'app' object.
(I think).

Also, I am very lazy, so I think I'll implement an auto-parenthesis function.
I find it awkward to have to write app.quit() when I can write app.quit instead. :mrgreen:
Unless it's carrying parameters, of course.

Re: A Lua in game console.

Posted: Sat Jan 23, 2010 10:46 pm
by merlinblack
Yeah, I've been thinking about auto-complete myself. I might just go for tab-complete, i.e. rather than automatic, trigger it on the tab key. I'll probably write it in Lua to start with too.

I'm using the latest luabind (.9) for most of my binding where classes are involved. Otherwise I just make a free function and use good old lua_register.

Auto parentheses make sense to me, being a game console. I think I'll do that too :D

Nigel

Re: A Lua in game console.

Posted: Sat Feb 06, 2010 6:51 pm
by KakCAT
bug... maybe

Code: Select all

        case OIS::KC_DOWN:
            if( !history.empty() )
            {
              history_line++;
shouldn't be

Code: Select all

        case OIS::KC_DOWN:
            if( !history.empty() )
            {
                if( history_line != history.end() )  history_line++;

??

I'm getting a "list iterator not incrementable" error when I press "down" just after adding an item to the history, due to

Code: Select all

void LuaConsole::addToHistory( const string& cmd )
{
   ....
    history_line = history.end();
}

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 1:12 am
by Charlie111
Hi,

I'm using the lua console, it's cool :D
Only little problem : I can't get the console to be transparent.
I will not bother you with the code... but is there a classical mistake that I could have done ??
Actually, even if I change the color (not transparance), the font of the console remain white.
So I think that I don't set the material correctly...

juts a little part for fun

Code: Select all

m_TextBox = overlayManager.createOverlayElement("TextArea","ConsoleText");
m_TextBox->setMetricsMode(GMM_RELATIVE);
m_TextBox->setPosition(0,0);
m_TextBox->setParameter("font_name","Console");
m_TextBox->setParameter("colour_top","0 0 0");
m_TextBox->setParameter("colour_bottom","0 0 0");
m_TextBox->setParameter("char_height","0.03");

m_Panel = static_cast<OverlayContainer*>(overlayManager.createOverlayElement("Panel", "ConsolePanel"));
m_Panel->setMetricsMode(Ogre::GMM_RELATIVE);
m_Panel->setPosition(0, 0);
m_Panel->setDimensions(1, 0);
m_Panel->setMaterialName("console/background");

m_Panel->addChild(m_TextBox);

m_Overlay = overlayManager.create("Console");
m_Overlay->add2D(m_Panel);
m_Overlay->show();
The material

Code: Select all

material console/background 
{ 
	technique 
	{ 
		pass 
		{ 
			scene_blend alpha_blend
			diffuse 0 0.3 1 0.5 
		}
	} 
} 
Thanks !

++

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 4:34 am
by jacmoe
To be honest, that console material has me baffled as well, so I just ended up using a real texture! :)
KakCAT wrote:

Code: Select all

if( history_line != history.end() )  history_line++;
Thanks for the fix!
Feel free to update the wiki - I tried pressing down with only one entry, and it did crash thoroughly. :)

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 12:32 pm
by merlinblack
I'm just using a texture for the console background.

Code: Select all

material console/background
{
	technique
	{
		pass
		{
			scene_blend modulate
         texture_unit
			{
			    texture console.png
			}
		}
	}
}


Now I think about it, I'm not sure where that material on the wiki came from. I must have pasted the wrong one!!! :oops:

My code isn't crashing after adding a line to the history, and pressing DOWN. :? Huh? My code seems the same as on the wiki...

I'll have to check that out! Because I'm using gcc on Linux? Just lucky. Who knows. :?

EDIT: I checked it out. Using "g++ (Ubuntu 4.4.1-4ubuntu9) 4.4.1", the following prints the message....

Code: Select all

iter = mylist.end();
iter++;
if( iter == mylist.begin() )
    cout << "Well that's interesting!!!" << endl;
END EDIT

I'll up date the wiki with your fix. Thanks!

On another note, I've implemented "auto-parenthesis" but its a little ...... hacky. It works however and is really cool. Thanks Jacmoe for the idea! :D

I'm wondering if to update the wiki page, or perhaps make an 'additions page'. I have other things, like a simple binding of console functions to Lua, that I could add.

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 12:44 pm
by merlinblack
Here's my changes to luainterpreter.cpp to give you "auto-parenthesis".

Code: Select all

// Insert (another) line of text into the interpreter.
LuaInterpreter::State LuaInterpreter::insertLine( std::string& line, bool fInsertInOutput )
{
    if( fInsertInOutput == true )
    {
        mOutput += line;
        mOutput += '\n';
    }

    if( mFirstLine && line.substr(0,1) == "=" )
    {
        line = "return " + line.substr(1, line.length()-1 );
    }

    mCurrentStatement += " ";
    mCurrentStatement += line;
    mFirstLine = false;

    mState = LI_READY;

    if( luaL_loadstring( mL, mCurrentStatement.c_str() ) )
    {
        string error( lua_tostring( mL, -1 ) );
        lua_pop( mL, 1 );

        // If the error is not a syntax error cuased by not enough of the
        // statement been yet entered...
        if( error.substr( error.length()-6, 5 ) != "<eof>" )
        {
            mOutput += error;
            mOutput += "\n";
            mOutput += LI_PROMPT;
            mCurrentStatement.clear();
            mState = LI_ERROR;

            return mState;
        }
        // Otherwise...
        else
        {
            // Try putting "()" on the end.  This allows commands such as 'quit' to invoke 'quit()'
            if( luaL_loadstring( mL, (mCurrentStatement + "()").c_str() ) )
            {
                // Didn't work.  Remove error message.
                lua_pop( mL, 1 );

                // Secondary prompt
                mPrompt = LI_PROMPT2;

                mState = LI_NEED_MORE_INPUT;

                return mState;
            }
        }
    }

    // The statment compiled correctly, now run it.

    if( ! lua_pcall( mL, 0, LUA_MULTRET, 0 ) )
    {
        // The error message (if any) will be added to the output as part
        // of the stack reporting.
        lua_gc( mL, LUA_GCCOLLECT, 0 );     // Do a full garbage collection on errors.
        mState = LI_ERROR;
    }

    mCurrentStatement.clear();
    mFirstLine = true;

    // Report stack contents
    if ( lua_gettop(mL) > 0)
    {
      lua_getglobal(mL, "print");
      lua_insert(mL, 1);
      lua_pcall(mL, lua_gettop(mL)-1, 0, 0);
    }

    mPrompt = LI_PROMPT;

    // Clear stack
    lua_settop( mL, 0 );

    return mState;
}
Basically if the code fails to compile due to there being not enough yet entered, "()" is added to the end and compiling it tried again. So at the console "quit" becomes "quit()" for example. It adds more "exits" from the function than I would like, but it seems to work. 8)

And here is a superior alternate to the output stuff in luainterpreter.cpp

Code: Select all

int LuaConsole_print( lua_State *L )
{
    int i;
    int nArgs = lua_gettop(L);
    std::string output;

    lua_getglobal( L, "tostring" );

    for( i = 1; i <= nArgs; i++ )
    {
        const char *s;
        lua_pushvalue( L, -1 );
        lua_pushvalue( L, i );
        lua_pcall( L, 1, 1, 0 );
        s = lua_tostring( L, -1 );
        if( ! s )
            return luaL_error( L, LUA_QL("tostring") " must return a string to ", LUA_QL("print"));

        output += s;

        if( i < nArgs )
            output += "\t";

        lua_pop( L, 1 );    // Pop return value of "tostring"
    }

    LuaConsole::getSingleton().print( output );

    return 0;
}
It prints straight to the console class, so you see the result as soon as it happens without having to press enter to see new output. Also handles anything that "tostring()" handles, since that's what it uses! As per usual, I wrote it, then found something almost identical on the net. So it's got the good bits of that added too. :)

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 6:21 pm
by jacmoe
My solution for the auto-parenthesis is here:

Code: Select all

			std::string sought = "(";
			int pos = mCurrentStatement.find(sought);
			if(pos == std::string::npos)
			{
				mCurrentStatement += std::string("()");
			}
			execString(mCurrentStatement);
Seems to work! :)

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 9:50 pm
by merlinblack
Hey Jacmoe,
Do you with your Anglescript interpreter support splitting a 'statement' across lines? I studied how it was done in lua.c, so I could enter for example:

Code: Select all

function test() <enter>
print 'Hello' <enter> 
end <enter>
On previous attempts, I didn't do this, and had to enter functions on a single line, which sucked! :P

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 10:46 pm
by jacmoe
I am using a Angelscript executeString helper function at the moment which does the final wrapping, but without using that: yes, it would support multiple lines.
But then you would need either a end-of-script indicator, or a button ('Compile and Run').
I think as a simple console, the simple executeString function does the job.
Let's see. :)

Re: A Lua in game console.

Posted: Sun Feb 07, 2010 11:10 pm
by merlinblack
You can't do something similar to how my Lua one works? Basically it tries to execute what's entered so far, and if it fails with a "end of file" error, it gives you the chance to add more. (Also now tries sticking "()" on the end as well.

Re: A Lua in game console.

Posted: Mon Feb 08, 2010 1:55 am
by jacmoe
I can probably do that - haven't looked at it much, to be honest. :)
Tdev from RoR can probably answer your question as he's got a fullblown Angelscript console going.

Re: A Lua in game console.

Posted: Wed Feb 10, 2010 3:41 pm
by jacmoe
I am working on a Lisp in game console :)
Will post code when it's done.

Re: A Lua in game console.

Posted: Thu Feb 11, 2010 4:11 pm
by jacmoe
lispConsole.jpg
lispConsole.jpg (44.34 KiB) Viewed 17250 times
:)

Turned out to be simple enough, using ECL.
You have to use C though, but that's not a problem (for me):

Code: Select all

void eclInitCallbacks()
{
	eclCall("(in-package user)");
	cl_def_c_function(c_string_to_object("quit"), (cl_objectfn_fixed)cbQuit, 0);
	eclCall("(in-package user)");
}

cl_object cbQuit()
{
	eclTest::getSingleton().shutdown();

	return Ct;
}
Singletons are really handy when using C code for interfacing.

I'll post some code if someone is interested (and probably after working with it a bit more), but it seems to work nicely. :wink: