There are a couple of topics on setting up your own ScriptModule, but most of them seem to be to do with LUA, and I don't want to use that. There is one here that looks very similar to what I want, but it is a bit different and doesn't have enough info for me to get mine working.
I want to basically handle ALL events from all gui elements that I set up an Event element for in my layout file with 1 routine. I should then be able to deduce what event was fired from this routine and take action accordingly. The reason I want to do this is that I want to pass the event information out to another program, and so having info about any events that occur would be great.
To do this I thing I need to set up a custom command interpreter similar to this article in the wiki: http://www.cegui.org.uk/wiki/index.php/ ... tingModule
However, for me I have set this up and am not getting any events triggered. I have the event in my layout file attached to a button. I am getting the following error in my CEGUI.log:
29/03/2011 22:57:21 (Std) ---- Version 0.7.5 (Build: Mar 22 2011 Static Microsoft Windows MSVC++ 10.0 32 bit) ----
29/03/2011 22:57:21 (Std) ---- Renderer module is: CEGUI::Direct3D9Renderer - Official Direct3D 9 based 2nd generation renderer module. ----
29/03/2011 22:57:21 (Std) ---- XML Parser module is: CEGUI::ExpatParser - Official expat based parser module for CEGUI ----
29/03/2011 22:57:21 (Std) ---- Image Codec module is: SILLYImageCodec - Official SILLY based image codec ----
29/03/2011 22:57:21 (Std) ---- Scripting module is: None ----
... snip ...
29/03/2011 22:57:21 (Info) Assigning LookNFeel 'TaharezLook/Button' to window 'MyApp/Quit'.
29/03/2011 22:57:21 (Error) CEGUI::InvalidRequestException in file ..\..\..\cegui\src\CEGUIEventSet.cpp(122) : [EventSet::subscribeScriptedEvent] No scripting module is available
29/03/2011 22:57:21 (Std) ---- Successfully completed loading of GUI layout from 'MyApp.layout' ----
29/03/2011 22:57:21 (Std) ---- Scripting module is now: Unknown scripting module (vendor did not set the ID string!) ----
29/03/2011 22:57:21 (Std) Attempting to create Imageset 'DejaVuSans-10_auto_glyph_images_ ' with texture only.
I have the classes as per the above wiki link in my source for classes "ScriptingModule" and "CommandInterpretor" [sic] set up as follows:
Code: Select all
/// Callback for a event command
class CommandInterpretor
{
public:
CommandInterpretor(const std::string& event_name, const std::string& subscriber_name)
: evt_name(event_name), sub_name(subscriber_name)
{}
bool operator()(const CEGUI::EventArgs& args) const
{
//std::cout << m_name ;
OutputDebugString( "MyApp: EVENT_NAME: " );
OutputDebugString( evt_name.c_str() );
OutputDebugString( "MyApp: EVENT_SUBSCRIBER: " );
OutputDebugString( sub_name.c_str() );
const CEGUI::WindowEventArgs* argument = dynamic_cast<const CEGUI::WindowEventArgs*>(&args) ;
if (argument)
{
// we have the window that triggered the event
///std::cout << " " << argument->window->getName() ;
OutputDebugString( "MyApp: WINDOWNAME: " );
OutputDebugString( argument->window->getName().c_str() );
}
//std::cout << std::endl ;
return true ;
}
std::string sub_name ;
std::string evt_name ;
};
/// Specialized scripting module for CEGUI
class ScriptingModule : public CEGUI::ScriptModule
{
public:
virtual CEGUI::Event::Connection subscribeEvent(
CEGUI::EventSet* target,
const CEGUI::String& name,
const CEGUI::String& subscriber_name)
{
OutputDebugString( "MyApp: EVENTSUB 1 #######################" );
CommandInterpretor command(name.c_str(), subscriber_name.c_str()) ;
return target->subscribeEvent(name,CEGUI::Event::Subscriber(command)) ;
}
virtual CEGUI::Event::Connection subscribeEvent(
CEGUI::EventSet* target,
const CEGUI::String& event_name,
CEGUI::Event::Group group,
const CEGUI::String& subscriber_name)
{
OutputDebugString( "MyApp: EVENTSUB 2 #######################" );
CommandInterpretor command(event_name.c_str(), subscriber_name.c_str()) ;
return target->subscribeEvent(event_name,group,CEGUI::Event::Subscriber(command)) ;
}
virtual void executeScriptFile(const CEGUI::String &filename, const CEGUI::String &resourceGroup="")
{}
virtual int executeScriptGlobal(const CEGUI::String& function_name)
{
return 0 ;
}
virtual void executeString(const CEGUI::String &str)
{
}
virtual bool executeScriptedEventHandler(
const CEGUI::String& handler_name,
const CEGUI::EventArgs &e)
{
return true ;
}
};
Now I realise I haave probably done something really obvious but I have spent a coupleof hours looking for what I have done wrong, and can't find it. I am fairly new to C++ (having only used C) and so OOP is still somewhat unfamiliar. I am trying to learn gradually, but I wondered if someone might take a look and see what is wrong? It may be a problem with the "module" setup in the below section of code, but I don't know what do do other than set up a new instance of "ScriptingModule" and pass it to the system using CEGUI::System::getSingleton().setScriptingModule( module )... please have mercy
Here is the init code where I am setting things up:
Code: Select all
Init()
{
using namespace CEGUI;
try
{
new CEGUI::DefaultLogger();
CEGUI::DefaultLogger::getSingleton().setLoggingLevel(CEGUI::Informative);
SetWindowLong(pimpl->d_window, GWL_WNDPROC, (long)Win32AppHelper::wndProc);
pimpl->d_renderer = &CEGUI::Direct3D9Renderer::bootstrapSystem(m_device);
SetResourceGroupStuff();
// setup default group for validation schemas
CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
parser->setProperty("SchemaDefaultResourceGroup", "schemas");
CEGUI::SchemeManager::getSingleton().create( GuiScheme );
CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton();
CEGUI::Window *sheet;
sheet = winMgr.loadWindowLayout( GuiLayout );
system::getSingleton().setGUISheet( sheet );
ScriptingModule *module = new ScriptingModule;
CEGUI::System::getSingleton().setScriptingModule( module ) ;
}
catch (CEGUI::Exception e)
{
OutputDebugString( "MyApp: Init() -> bootstrapSystem FAILED" );
OutputDebugString( e.what() );
MessageBox(NULL, e.getMessage().c_str(), "Error initializing the GUI", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}
}
Here is where I am injecting inputs, etc:
Code: Select all
CEGUI::System& guiSystem = CEGUI::System::getSingleton();
Win32AppHelper::doWin32Events(idle);
DWORD thisTime = GetTickCount();
float elapsed = static_cast<float>(thisTime - d_lastFrameTime);
d_lastFrameTime = thisTime;
// inject the time pulse
guiSystem.injectTimePulse(elapsed / 1000.0f);
try
{
guiSystem.renderGUI();
}
catch (CEGUI::Exception e)
{
OutputDebugString( "MyApp: EndScene() -> renderGUI() FAILED: " );
OutputDebugString( e.what() );
}
Here is my layout file (I set an Event element on the Quit button):
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<GUILayout >
<Window Type="DefaultWindow" Name="Root" >
<Property Name="InheritsAlpha" Value="False" />
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
<Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
<Window Type="TaharezLook/FrameWindow" Name="MyApp" >
<Property Name="Text" Value="Text sample" />
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
<Property Name="TitlebarEnabled" Value="True" />
<Property Name="UnifiedAreaRect" Value="{{0.0160194,0},{0.0159533,0},{0.869175,0},{0.880739,0}}" />
<Window Type="TaharezLook/Button" Name="MyApp/Quit" >
<Property Name="Text" Value="Quit" />
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
<Property Name="UnifiedAreaRect" Value="{{0.421905,0},{0.937908,0},{0.612162,0},{0.991433,0}}" />
<Event Name="Clicked" Function="play"/>
</Window>
</Window>
</Window>
</GUILayout>