Widestring Loading

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Arclamp
Posts: 71
Joined: Thu Oct 10, 2013 7:45 pm

Widestring Loading

Post by Arclamp »

I'm trying to load widestring content from xml file to gui element, but it goes wrong at the last step of the demos version 3.

Version 1 proves it can load the wide chars directly from string.

Version 2 proves it can use an IAttributes for the job

Version 3 is proved right up until the transfer from the IAttributes to the element... This doesn't make sense to me considering version 2, what go on??? :D


*** Requires own CGUIFreetypeFont for demo...

Code: Select all

 
#include <iostream>
 
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
 
#include "NUBFont.h"
 
IrrlichtDevice* device;
IVideoDriver* driver;
ISceneManager* smgr;
IGUIEnvironment* env;
 
enum RXKeyStates { KSTATE_UP, KSTATE_DOWN, KSTATE_HELD, KSTATE_RELEASED };
 
class MyEventReceiver : public IEventReceiver
{
public:
    MyEventReceiver(scene::ISceneManager* SceneManager)
        : SceneManager(smgr)
    {
        //  GET SCENE MANAGER
        SceneManager->grab();
        
        //  INIT KEY ARRAY
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = KSTATE_UP;
    }
 
    virtual ~MyEventReceiver()
    {
        SceneManager->drop();
    }
    
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == irr::EET_KEY_INPUT_EVENT){
            //  KEYS... 0=up,1=down,2=hold,3=release
            if(event.KeyInput.PressedDown){ //  PRESSED DOWN
                if(KeyIsDown[event.KeyInput.Key]==KSTATE_UP){   KeyIsDown[event.KeyInput.Key]=KSTATE_DOWN;  }   //  INITIAL DOWN
            }else{  //  PRESSED UP
                KeyIsDown[event.KeyInput.Key]=KSTATE_RELEASED;  //  RELEASED
            }
        }
 
        return false;
    }
    
    virtual void cycle_end(){
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i){
            //KeyIsDown[i] = false;
            if(KeyIsDown[i]==KSTATE_DOWN){ KeyIsDown[i]=KSTATE_HELD;    }
            else if(KeyIsDown[i]==KSTATE_RELEASED){ KeyIsDown[i]=KSTATE_UP; }
        }
    }
    
    // This is used to check whether a key is being held down
    virtual s32 getKey(EKEY_CODE keyCode) const{
        return KeyIsDown[keyCode];      //  KEYS... 0=up,1=down,2=hold,3=release
    }
 
private:
    scene::ISceneManager* SceneManager;
    // KEY STATES
    s32 KeyIsDown[KEY_KEY_CODES_COUNT];
public:
};
 
 
core::array<IAttributes*> load_xml_quick_file(io::path fn)
{
    //  DECLARE RETURN
    core::array<IAttributes*> bag;
    
    if(!device)
    {
        return bag;
    }
    
    irr::io::IXMLReader* xml = device->getFileSystem()->createXMLReader(fn);
    //irr::io::IXMLReaderUTF8* xml = device->getFileSystem()->createXMLReaderUTF8(fn);
    if(!xml)
    {
        return bag;
    }
    
    //return load_xml_quick_xml(xml);
    
    //  PARSE XML DOC
    while (xml->read())
    {
        switch (xml->getNodeType())
        {
            case irr::io::EXN_ELEMENT:
                {
                    //stringw key = xml->getAttributeValueSafe(L"name");
                    
                    //  NEW ATTRIBUTES
                    io::IAttributes *attr = device->getFileSystem()->createEmptyAttributes(driver);
                    
                    //  NODE NAME
                    std::wcout << " NodeName: " << xml->getNodeName() << std::endl;
                    attr->addString("___node_name", xml->getNodeName());
                    
                    //  PARSE ATTRIBUTES
                    u32 tot = xml->getAttributeCount();
                    for(u32 i = 0; i < tot; i++)
                    {
                        //core::stringw sw = xml->getAttributeAsStringW(i);
                        core::stringw sw = xml->getAttributeValue(i);
                        core::stringc sname = xml->getAttributeName(i);
                        
                        attr->addString(sname.c_str(), sw.c_str());
                        
                        std::wcout << "         attr: " << sname.c_str() << ", " << sw.c_str() << std::endl;
                    }
                    
                    //  IF WE HAVE ID
                    //s32 id =
                    
                    //  PUSH ITEM
                    bag.push_back(attr);
                    
                }
                break;
            
            default:
                break;
        }
    }
    
    //  CLEAN
    xml->drop();
    
    return bag;
}
 
 
void test_01()
{
    
    //  VERSION 1: Straight from string
    core::stringw sw = L"Hello \u2296 \u2297 \u2298 \u2299 Ø   Ξ .Ä.\u00c4.....\u0054.\u0444.ф.Text\u0444 \u0445 \u0446 \u211C \u2227 \u2228 ";
    env->addStaticText(sw.c_str(), core::rect<s32>(10,100,790,130), false, false, NULL, -1, true);
    
    
    
    
    //  VERSION 2: From string to attribute and back
    sw = L"Hello Ø Ξ";
    IAttributes* attr = device->getFileSystem()->createEmptyAttributes(driver);
    attr->addString("text", sw.c_str());
    env->addStaticText(attr->getAttributeAsStringW("text").c_str(), core::rect<s32>(10,150,790,180), false, false, NULL, -1, true);
    
    
    
    //  VERSION 3: Load from file, to attribute and back
    io::path fn = "media/config.xml";
    core::array<IAttributes*> aa = load_xml_quick_file(fn);
    
    for(u32 i = 0; i < aa.size(); i++)
    {
        std::wcout << "" << aa[i]->getAttributeAsStringW("label").c_str() << std::endl;
        env->addStaticText(aa[i]->getAttributeAsStringW("label").c_str(), core::rect<s32>(10,200+((i+1)*30),790,220+((i+1)*30)), false, false, NULL, -1, true);
    }
    
}
 
int main()
{
    
    device = createDevice(video::EDT_OPENGL, dimension2d<u32>(800, 400), 16, false, false, false);
    if (device == 0)
        return 1; // could not create selected driver.
    driver = device->getVideoDriver();
    smgr = device->getSceneManager();
    env = device->getGUIEnvironment();
    
    MyEventReceiver receiver(smgr);
    device->setEventReceiver(&receiver);
    
    
    IGUISkin* skin = env->getSkin();
    IGUIFont* font = env->getFont("media/fonthaettenschweiler.bmp");
    if (font)
        skin->setFont(font);
    
    //  LOAD TTF FONT           *** TODO: SWAP THIS WITH YOUR CGUIFreetypeFont IMPLEMENTATION...!!!
    NUBFont *f0 = new NUBFont(env, "media/fonts/FreeMonoBold.ttf", "", "", 18);     //  env, fn, name, quickname, size
    skin->setFont(f0->font);
    
    //  TEST
    test_01();
    
    bool run = true;
    while(device && device->run() && run)
    {
        if(device->isWindowActive())
        {
            if(receiver.getKey(irr::KEY_ESCAPE)==KSTATE_RELEASED)
                run = false;
        
            driver->beginScene(true, true, video::SColor(0,55,55,55));
            smgr->drawAll();
            env->drawAll();
            driver->endScene();
            
            receiver.cycle_end();
              
        }else{
            device->yield();
        }
    }
    device->drop();
}
 
media/config.xml

Code: Select all

 
<?xml version="1.0" encoding="UTF-16"?>
<element label="A  \u0446 \u211C \u2227 \u2228" />
<element label="B Ø Ξ .Ä." />
<element label="C" />
 
<!--
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-16"?>
<?xml version="1.0" encoding="iso-8859-1" ?>
-->
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Widestring Loading

Post by CuteAlien »

What is going wrong? I notice I can't compile your first example on VS (but maybe only on older VS which I used right now) because of the unicode characters. And I have right now no easy test for TTF (needs some work because of missing truetype lib or reboot to get to other OS, sorry...). But in debugger I can see it loads the XML correct and the attributes contain the unicode. Well at least for the "B" case.

So what is missing - do you get wrong output? Maybe add a quick screenshot. And check what you have in the debugger.
Also - which compiler is this? I can maybe try again with newer VS or some gcc version.

edit: And because I like doing unrelated comments on code... _always_ initialize all pointers with 0 (or nullptr when you use c++11) unless you have a really, really good reason to not do that. Otherwise your checks for 0 give me the creeps :-)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply