I succesfully added a LUA bind to the "engine" the book make us do.
First of all I get
LUA library and
Lua SLB, wich is a binder for C++. You can find it here :
http://code.google.com/p/slb/I used the version 2 because I had already used it in the past, but version 3 should be fine.
I dunno if what I did is the best way to do, but here it is :
- I added LUA and Lua SLB headers to my project
- In the
ResourcesIdentifiers I added a
Scripts namespace with an enum of my scripts
- I created a
ScriptPlayer class witch the equivalent of
MusicPlayer but for LUA scripts. It has two methods to load scripts :
registerFile() and
regsterScript() because a LUA script can be in a file or directly in C++ string. The
ScriptPlayer is also responsible for storing the
lua_State pointer. I pass it to my
SceneNode in the Application Context (with other resources managers).
- Then I added a
ScriptNode wich keep a pointer onto the
ScriptPlayer and plays a script under a certain command or at update or as you want...
- I added functions that bind my essential C++ classes to LUA with SLB. For now I just binded sf::Vector2f, SceneNode and Entity for tests purposes, but you can bind whatever you want.
The result is that I can make a fight between David and Goliath (wich are Entities) in LUA, even move them if I want to :
SLB.using(SLB);
local david = Entity(100);
local goliath = Entity(200);
local position = david:getWorldPosition();
--print("David is at (".. position.x ..":".. position.y ..")");
while ((not david:isDestroyed()) and (not goliath:isDestroyed())) do
if (david:getHealthpoints() < 80) then
-- Heal himself
david:heal(30);
else
-- David attack Goliath
goliath:damage(10);
end
-- Goliath attacks David
david:damage(20);
-- Recap
print("\n----------------------------");
print("David: "..david:getHealthpoints().."HP");
print("Goliath: "..goliath:getHealthpoints().."HP");
print("\n");
end
Exposal look like this :
void exposeVector()
{
SLB::Class<sf::Vector2f>("Vector2f")
.constructor<float, float>()
.property("x", &sf::Vector2f::x)
.property("y", &sf::Vector2f::y);
}
void exposeSceneNode()
{
SLB::Class<SceneNode, SLB::Instance::NoCopy>("SceneNode")
.constructor<Category::Type>()
.set("getWorldPosition", &SceneNode::getWorldPosition);
}
And the ScriptPlayer definition :
class ScriptPlayer : private sf::NonCopyable
{
public:
ScriptPlayer();
~ScriptPlayer();
bool play(Scripts::ID script);
void registerFile(Scripts::ID script, const std::string& filename);
void registerScript(Scripts::ID script, const std::string& content);
private:
lua_State* mLuaState;
std::map<Scripts::ID, std::string> mScripts;
};
If you want to have more sources about that, you're welcome to get an eye on my GitHub repo :
https://github.com/Lo-X/potato-frameworkYou may (and must :p ) need to read the book to understand the "framework"
As I already said, I'm not sure this way to do is the best, but as far as my tests go, it works