<commit_before>/*
-----------------------------------------------------------------------------
Filename:    BaseApplication.cpp
-----------------------------------------------------------------------------

This source file is part of the
   ___                 __    __ _ _    _
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/
Tutorial Framework (for Ogre 1.9)
http://www.ogre3d.org/wiki/
-----------------------------------------------------------------------------
*/

#include "BaseApplication.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <macUtils.h>
#endif

//---------------------------------------------------------------------------
BaseApplication::BaseApplication(void)
    : mRoot(0),
    mCamera(0),
    mSceneMgr(0),
    mWindow(0),
    mResourcesCfg(Ogre::StringUtil::BLANK),
    mPluginsCfg(Ogre::StringUtil::BLANK),
    mTrayMgr(0),
    mCameraMan(0),
    mDetailsPanel(0),
    mCursorWasVisible(false),
    mShutDown(false),
    mInputManager(0),
    mMouse(0),
    mKeyboard(0),
    mOverlaySystem(0)
{
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
    m_ResourcePath = Ogre::macBundlePath() + "/Contents/Resources/";
#else
    m_ResourcePath = "";
#endif
}

//---------------------------------------------------------------------------
BaseApplication::~BaseApplication(void)
{
    if (mTrayMgr) delete mTrayMgr;
    if (mCameraMan) delete mCameraMan;
    if (mOverlaySystem) delete mOverlaySystem;

    // Remove ourself as a Window listener
    Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
    windowClosed(mWindow);
    delete mRoot;
}

//---------------------------------------------------------------------------
bool BaseApplication::configure(void)
{
    // Show the configuration dialog and initialise the system.
    // You can skip this and use root.restoreConfig() to load configuration
    // settings if you were sure there are valid ones saved in ogre.cfg.
    if(mRoot->showConfigDialog())
    {
        // If returned true, user clicked OK so initialise.
        // Here we choose to let the system create a default rendering window by passing 'true'.
        mWindow = mRoot->initialise(true, "TutorialApplication Render Window");

        return true;
    }
    else
    {
        return false;
    }
}
//---------------------------------------------------------------------------
void BaseApplication::chooseSceneManager(void)
{
    // Get the SceneManager, in this case a generic one
    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);

    // Initialize the OverlaySystem (changed for Ogre 1.9)
    mOverlaySystem = new Ogre::OverlaySystem();
    mSceneMgr->addRenderQueueListener(mOverlaySystem);
}
//---------------------------------------------------------------------------
void BaseApplication::createCamera(void)
{
    // Create the camera
    mCamera = mSceneMgr->createCamera("PlayerCam");

    // Position it at 500 in Z direction
    mCamera->setPosition(Ogre::Vector3(0,0,80));
    // Look back along -Z
    mCamera->lookAt(Ogre::Vector3(0,0,-300));
    mCamera->setNearClipDistance(5);

    mCameraMan = new OgreBites::SdkCameraMan(mCamera);   // Create a default camera controller
}
//---------------------------------------------------------------------------
void BaseApplication::createFrameListener(void)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
    OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;

    mWindow->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

    mInputManager = OIS::InputManager::createInputSystem(pl);

    mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true));
    mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true));

    mMouse->setEventCallback(this);
    mKeyboard->setEventCallback(this);

    // Set initial mouse clipping size
    windowResized(mWindow);

    // Register as a Window listener
    Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);

    mInputContext.mKeyboard = mKeyboard;
    mInputContext.mMouse = mMouse;
    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mInputContext, this);
    mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
    mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);
    mTrayMgr->hideCursor();

    // Create a params panel for displaying sample details
    Ogre::StringVector items;
    items.push_back("cam.pX");
    items.push_back("cam.pY");
    items.push_back("cam.pZ");
    items.push_back("");
    items.push_back("cam.oW");
    items.push_back("cam.oX");
    items.push_back("cam.oY");
    items.push_back("cam.oZ");
    items.push_back("");
    items.push_back("Filtering");
    items.push_back("Poly Mode");

    mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items);
    mDetailsPanel->setParamValue(9, "Bilinear");
    mDetailsPanel->setParamValue(10, "Solid");
    mDetailsPanel->hide();

    mRoot->addFrameListener(this);
}
//---------------------------------------------------------------------------
void BaseApplication::destroyScene(void)
{
}
//---------------------------------------------------------------------------
void BaseApplication::createViewports(void)
{
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

    // Alter the camera aspect ratio to match the viewport
    mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
}
//---------------------------------------------------------------------------
void BaseApplication::setupResources(void)
{
    // Load resource paths from config file
    Ogre::ConfigFile cf;
    cf.load(mResourcesCfg);

    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
            // OS X does not set the working directory relative to the app.
            // In order to make things portable on OS X we need to provide
            // the loading with it's own bundle path location.
            if (!Ogre::StringUtil::startsWith(archName, "/", false)) // only adjust relative directories
                archName = Ogre::String(Ogre::macBundlePath() + "/" + archName);
#endif

            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
}
//---------------------------------------------------------------------------
void BaseApplication::createResourceListener(void)
{
}
//---------------------------------------------------------------------------
void BaseApplication::loadResources(void)
{
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
//---------------------------------------------------------------------------
void BaseApplication::go(void)
{
#ifdef _DEBUG
#ifndef OGRE_STATIC_LIB
    mResourcesCfg = m_ResourcePath + "resources_d.cfg";
    mPluginsCfg = m_ResourcePath + "plugins_d.cfg";
#else
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#endif
#else
#ifndef OGRE_STATIC_LIB
    mResourcesCfg = m_ResourcePath + "resources.cfg";
    mPluginsCfg = m_ResourcePath + "plugins.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif
#endif

    if (!setup())
        return;

    mRoot->startRendering();

    // Clean up
    destroyScene();
}
//---------------------------------------------------------------------------
bool BaseApplication::setup(void)
{
    mRoot = new Ogre::Root(mPluginsCfg);

    setupResources();

    bool carryOn = configure();
    if (!carryOn) return false;

    chooseSceneManager();
    createCamera();
    createViewports();

    // Set default mipmap level (NB some APIs ignore this)
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);

    // Create any resource listeners (for loading screens)
    createResourceListener();
    // Load resources
    loadResources();

    // Create the scene
    createScene();

    createFrameListener();

    return true;
};
//---------------------------------------------------------------------------
bool BaseApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    if(mWindow->isClosed())
        return false;

    if(mShutDown)
        return false;

    // Need to capture/update each device
    mKeyboard->capture();
    mMouse->capture();

    mTrayMgr->frameRenderingQueued(evt);

    if (!mTrayMgr->isDialogVisible())
    {
       /* mCameraMan->frameRenderingQueued(evt);  */ // If dialog isn't up, then update the camera
        if (mDetailsPanel->isVisible())          // If details panel is visible, then update its contents
        {
            mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(mCamera->getDerivedPosition().x));
            mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(mCamera->getDerivedPosition().y));
            mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(mCamera->getDerivedPosition().z));
            mDetailsPanel->setParamValue(4, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().w));
            mDetailsPanel->setParamValue(5, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().x));
            mDetailsPanel->setParamValue(6, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().y));
            mDetailsPanel->setParamValue(7, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().z));
        }
    }

    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::keyPressed( const OIS::KeyEvent &arg )
{
    if (mTrayMgr->isDialogVisible()) return true;   // don't process any more keys if dialog is up

    if (arg.key == OIS::KC_F)   // toggle visibility of advanced frame stats
    {
        mTrayMgr->toggleAdvancedFrameStats();
    }
    else if (arg.key == OIS::KC_G)   // toggle visibility of even rarer debugging details
    {
        if (mDetailsPanel->getTrayLocation() == OgreBites::TL_NONE)
        {
            mTrayMgr->moveWidgetToTray(mDetailsPanel, OgreBites::TL_TOPRIGHT, 0);
            mDetailsPanel->show();
        }
        else
        {
            mTrayMgr->removeWidgetFromTray(mDetailsPanel);
            mDetailsPanel->hide();
        }
    }
    else if (arg.key == OIS::KC_T)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::TextureFilterOptions tfo;
        unsigned int aniso;

        switch (mDetailsPanel->getParamValue(9).asUTF8()[0])
        {
        case 'B':
            newVal = "Trilinear";
            tfo = Ogre::TFO_TRILINEAR;
            aniso = 1;
            break;
        case 'T':
            newVal = "Anisotropic";
            tfo = Ogre::TFO_ANISOTROPIC;
            aniso = 8;
            break;
        case 'A':
            newVal = "None";
            tfo = Ogre::TFO_NONE;
            aniso = 1;
            break;
        default:
            newVal = "Bilinear";
            tfo = Ogre::TFO_BILINEAR;
            aniso = 1;
        }

        Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
        Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(aniso);
        mDetailsPanel->setParamValue(9, newVal);
    }
    else if (arg.key == OIS::KC_R)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::PolygonMode pm;

        switch (mCamera->getPolygonMode())
        {
        case Ogre::PM_SOLID:
            newVal = "Wireframe";
            pm = Ogre::PM_WIREFRAME;
            break;
        case Ogre::PM_WIREFRAME:
            newVal = "Points";
            pm = Ogre::PM_POINTS;
            break;
        default:
            newVal = "Solid";
            pm = Ogre::PM_SOLID;
        }

        mCamera->setPolygonMode(pm);
        mDetailsPanel->setParamValue(10, newVal);
    }
    else if(arg.key == OIS::KC_F5)   // refresh all textures
    {
        Ogre::TextureManager::getSingleton().reloadAll();
    }
    else if (arg.key == OIS::KC_SYSRQ)   // take a screenshot
    {
        mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
    }
    else if (arg.key == OIS::KC_ESCAPE)
    {
        mShutDown = true;
    }

   /* mCameraMan->injectKeyDown(arg);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::keyReleased(const OIS::KeyEvent &arg)
{
    /*mCameraMan->injectKeyUp(arg);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::mouseMoved(const OIS::MouseEvent &arg)
{
    if (mTrayMgr->injectMouseMove(arg)) return true;
   /* mCameraMan->injectMouseMove(arg);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
    if (mTrayMgr->injectMouseDown(arg, id)) return true;
    mCameraMan->injectMouseDown(arg, id);
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
    if (mTrayMgr->injectMouseUp(arg, id)) return true;
    mCameraMan->injectMouseUp(arg, id);
    return true;
}
//---------------------------------------------------------------------------
// Adjust mouse clipping area
void BaseApplication::windowResized(Ogre::RenderWindow* rw)
{
    unsigned int width, height, depth;
    int left, top;
    rw->getMetrics(width, height, depth, left, top);

    const OIS::MouseState &ms = mMouse->getMouseState();
    ms.width = width;
    ms.height = height;
}
//---------------------------------------------------------------------------
// Unattach OIS before window shutdown (very important under Linux)
void BaseApplication::windowClosed(Ogre::RenderWindow* rw)
{
    // Only close for window that created OIS (the main window in these demos)
    if(rw == mWindow)
    {
        if(mInputManager)
        {
            mInputManager->destroyInputObject(mMouse);
            mInputManager->destroyInputObject(mKeyboard);

            OIS::InputManager::destroyInputSystem(mInputManager);
            mInputManager = 0;
        }
    }
}
//---------------------------------------------------------------------------<commit_msg>Fixed mouseclick<commit_after>/*
-----------------------------------------------------------------------------
Filename:    BaseApplication.cpp
-----------------------------------------------------------------------------

This source file is part of the
   ___                 __    __ _ _    _
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/
Tutorial Framework (for Ogre 1.9)
http://www.ogre3d.org/wiki/
-----------------------------------------------------------------------------
*/

#include "BaseApplication.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <macUtils.h>
#endif

//---------------------------------------------------------------------------
BaseApplication::BaseApplication(void)
    : mRoot(0),
    mCamera(0),
    mSceneMgr(0),
    mWindow(0),
    mResourcesCfg(Ogre::StringUtil::BLANK),
    mPluginsCfg(Ogre::StringUtil::BLANK),
    mTrayMgr(0),
    mCameraMan(0),
    mDetailsPanel(0),
    mCursorWasVisible(false),
    mShutDown(false),
    mInputManager(0),
    mMouse(0),
    mKeyboard(0),
    mOverlaySystem(0)
{
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
    m_ResourcePath = Ogre::macBundlePath() + "/Contents/Resources/";
#else
    m_ResourcePath = "";
#endif
}

//---------------------------------------------------------------------------
BaseApplication::~BaseApplication(void)
{
    if (mTrayMgr) delete mTrayMgr;
    if (mCameraMan) delete mCameraMan;
    if (mOverlaySystem) delete mOverlaySystem;

    // Remove ourself as a Window listener
    Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
    windowClosed(mWindow);
    delete mRoot;
}

//---------------------------------------------------------------------------
bool BaseApplication::configure(void)
{
    // Show the configuration dialog and initialise the system.
    // You can skip this and use root.restoreConfig() to load configuration
    // settings if you were sure there are valid ones saved in ogre.cfg.
    if(mRoot->showConfigDialog())
    {
        // If returned true, user clicked OK so initialise.
        // Here we choose to let the system create a default rendering window by passing 'true'.
        mWindow = mRoot->initialise(true, "TutorialApplication Render Window");

        return true;
    }
    else
    {
        return false;
    }
}
//---------------------------------------------------------------------------
void BaseApplication::chooseSceneManager(void)
{
    // Get the SceneManager, in this case a generic one
    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);

    // Initialize the OverlaySystem (changed for Ogre 1.9)
    mOverlaySystem = new Ogre::OverlaySystem();
    mSceneMgr->addRenderQueueListener(mOverlaySystem);
}
//---------------------------------------------------------------------------
void BaseApplication::createCamera(void)
{
    // Create the camera
    mCamera = mSceneMgr->createCamera("PlayerCam");

    // Position it at 500 in Z direction
    mCamera->setPosition(Ogre::Vector3(0,0,80));
    // Look back along -Z
    mCamera->lookAt(Ogre::Vector3(0,0,-300));
    mCamera->setNearClipDistance(5);

    mCameraMan = new OgreBites::SdkCameraMan(mCamera);   // Create a default camera controller
}
//---------------------------------------------------------------------------
void BaseApplication::createFrameListener(void)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
    OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;

    mWindow->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

    mInputManager = OIS::InputManager::createInputSystem(pl);

    mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true));
    mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true));

    mMouse->setEventCallback(this);
    mKeyboard->setEventCallback(this);

    // Set initial mouse clipping size
    windowResized(mWindow);

    // Register as a Window listener
    Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);

    mInputContext.mKeyboard = mKeyboard;
    mInputContext.mMouse = mMouse;
    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mInputContext, this);
    mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
    mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);
    mTrayMgr->hideCursor();

    // Create a params panel for displaying sample details
    Ogre::StringVector items;
    items.push_back("cam.pX");
    items.push_back("cam.pY");
    items.push_back("cam.pZ");
    items.push_back("");
    items.push_back("cam.oW");
    items.push_back("cam.oX");
    items.push_back("cam.oY");
    items.push_back("cam.oZ");
    items.push_back("");
    items.push_back("Filtering");
    items.push_back("Poly Mode");

    mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items);
    mDetailsPanel->setParamValue(9, "Bilinear");
    mDetailsPanel->setParamValue(10, "Solid");
    mDetailsPanel->hide();

    mRoot->addFrameListener(this);
}
//---------------------------------------------------------------------------
void BaseApplication::destroyScene(void)
{
}
//---------------------------------------------------------------------------
void BaseApplication::createViewports(void)
{
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

    // Alter the camera aspect ratio to match the viewport
    mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
}
//---------------------------------------------------------------------------
void BaseApplication::setupResources(void)
{
    // Load resource paths from config file
    Ogre::ConfigFile cf;
    cf.load(mResourcesCfg);

    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
            // OS X does not set the working directory relative to the app.
            // In order to make things portable on OS X we need to provide
            // the loading with it's own bundle path location.
            if (!Ogre::StringUtil::startsWith(archName, "/", false)) // only adjust relative directories
                archName = Ogre::String(Ogre::macBundlePath() + "/" + archName);
#endif

            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
}
//---------------------------------------------------------------------------
void BaseApplication::createResourceListener(void)
{
}
//---------------------------------------------------------------------------
void BaseApplication::loadResources(void)
{
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
//---------------------------------------------------------------------------
void BaseApplication::go(void)
{
#ifdef _DEBUG
#ifndef OGRE_STATIC_LIB
    mResourcesCfg = m_ResourcePath + "resources_d.cfg";
    mPluginsCfg = m_ResourcePath + "plugins_d.cfg";
#else
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#endif
#else
#ifndef OGRE_STATIC_LIB
    mResourcesCfg = m_ResourcePath + "resources.cfg";
    mPluginsCfg = m_ResourcePath + "plugins.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif
#endif

    if (!setup())
        return;

    mRoot->startRendering();

    // Clean up
    destroyScene();
}
//---------------------------------------------------------------------------
bool BaseApplication::setup(void)
{
    mRoot = new Ogre::Root(mPluginsCfg);

    setupResources();

    bool carryOn = configure();
    if (!carryOn) return false;

    chooseSceneManager();
    createCamera();
    createViewports();

    // Set default mipmap level (NB some APIs ignore this)
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);

    // Create any resource listeners (for loading screens)
    createResourceListener();
    // Load resources
    loadResources();

    // Create the scene
    createScene();

    createFrameListener();

    return true;
};
//---------------------------------------------------------------------------
bool BaseApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    if(mWindow->isClosed())
        return false;

    if(mShutDown)
        return false;

    // Need to capture/update each device
    mKeyboard->capture();
    mMouse->capture();

    mTrayMgr->frameRenderingQueued(evt);

    if (!mTrayMgr->isDialogVisible())
    {
       /* mCameraMan->frameRenderingQueued(evt);  */ // If dialog isn't up, then update the camera
        if (mDetailsPanel->isVisible())          // If details panel is visible, then update its contents
        {
            mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(mCamera->getDerivedPosition().x));
            mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(mCamera->getDerivedPosition().y));
            mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(mCamera->getDerivedPosition().z));
            mDetailsPanel->setParamValue(4, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().w));
            mDetailsPanel->setParamValue(5, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().x));
            mDetailsPanel->setParamValue(6, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().y));
            mDetailsPanel->setParamValue(7, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().z));
        }
    }

    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::keyPressed( const OIS::KeyEvent &arg )
{
    if (mTrayMgr->isDialogVisible()) return true;   // don't process any more keys if dialog is up

    if (arg.key == OIS::KC_F)   // toggle visibility of advanced frame stats
    {
        mTrayMgr->toggleAdvancedFrameStats();
    }
    else if (arg.key == OIS::KC_G)   // toggle visibility of even rarer debugging details
    {
        if (mDetailsPanel->getTrayLocation() == OgreBites::TL_NONE)
        {
            mTrayMgr->moveWidgetToTray(mDetailsPanel, OgreBites::TL_TOPRIGHT, 0);
            mDetailsPanel->show();
        }
        else
        {
            mTrayMgr->removeWidgetFromTray(mDetailsPanel);
            mDetailsPanel->hide();
        }
    }
    else if (arg.key == OIS::KC_T)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::TextureFilterOptions tfo;
        unsigned int aniso;

        switch (mDetailsPanel->getParamValue(9).asUTF8()[0])
        {
        case 'B':
            newVal = "Trilinear";
            tfo = Ogre::TFO_TRILINEAR;
            aniso = 1;
            break;
        case 'T':
            newVal = "Anisotropic";
            tfo = Ogre::TFO_ANISOTROPIC;
            aniso = 8;
            break;
        case 'A':
            newVal = "None";
            tfo = Ogre::TFO_NONE;
            aniso = 1;
            break;
        default:
            newVal = "Bilinear";
            tfo = Ogre::TFO_BILINEAR;
            aniso = 1;
        }

        Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
        Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(aniso);
        mDetailsPanel->setParamValue(9, newVal);
    }
    else if (arg.key == OIS::KC_R)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::PolygonMode pm;

        switch (mCamera->getPolygonMode())
        {
        case Ogre::PM_SOLID:
            newVal = "Wireframe";
            pm = Ogre::PM_WIREFRAME;
            break;
        case Ogre::PM_WIREFRAME:
            newVal = "Points";
            pm = Ogre::PM_POINTS;
            break;
        default:
            newVal = "Solid";
            pm = Ogre::PM_SOLID;
        }

        mCamera->setPolygonMode(pm);
        mDetailsPanel->setParamValue(10, newVal);
    }
    else if(arg.key == OIS::KC_F5)   // refresh all textures
    {
        Ogre::TextureManager::getSingleton().reloadAll();
    }
    else if (arg.key == OIS::KC_SYSRQ)   // take a screenshot
    {
        mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
    }
    else if (arg.key == OIS::KC_ESCAPE)
    {
        mShutDown = true;
    }

   /* mCameraMan->injectKeyDown(arg);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::keyReleased(const OIS::KeyEvent &arg)
{
    /*mCameraMan->injectKeyUp(arg);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::mouseMoved(const OIS::MouseEvent &arg)
{
    if (mTrayMgr->injectMouseMove(arg)) return true;
   /* mCameraMan->injectMouseMove(arg);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
    if (mTrayMgr->injectMouseDown(arg, id)) return true;
    /*mCameraMan->injectMouseDown(arg, id);*/
    return true;
}
//---------------------------------------------------------------------------
bool BaseApplication::mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
    if (mTrayMgr->injectMouseUp(arg, id)) return true;
   // mCameraMan->injectMouseUp(arg, id);
    return true;
}
//---------------------------------------------------------------------------
// Adjust mouse clipping area
void BaseApplication::windowResized(Ogre::RenderWindow* rw)
{
    unsigned int width, height, depth;
    int left, top;
    rw->getMetrics(width, height, depth, left, top);

    const OIS::MouseState &ms = mMouse->getMouseState();
    ms.width = width;
    ms.height = height;
}
//---------------------------------------------------------------------------
// Unattach OIS before window shutdown (very important under Linux)
void BaseApplication::windowClosed(Ogre::RenderWindow* rw)
{
    // Only close for window that created OIS (the main window in these demos)
    if(rw == mWindow)
    {
        if(mInputManager)
        {
            mInputManager->destroyInputObject(mMouse);
            mInputManager->destroyInputObject(mKeyboard);

            OIS::InputManager::destroyInputSystem(mInputManager);
            mInputManager = 0;
        }
    }
}
//---------------------------------------------------------------------------<|endoftext|>


<commit_before>#include <string>
#include <typeinfo>
#include <iostream>

#include "cppa/test.hpp"
#include "cppa/util.hpp"

using std::cout;
using std::endl;

using namespace cppa;
using namespace cppa::util;

unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
{
	static_assert(sizeof(int) == 4,
				  "MurmurHash2 requires sizeof(int) == 4");

	// 'm' and 'r' are mixing constants generated offline.
	// They're not really 'magic', they just happen to work well.

	const unsigned int m = 0x5bd1e995;
	const int r = 24;

	// Initialize the hash to a 'random' value

	unsigned int h = seed ^ len;

	// Mix 4 bytes at a time into the hash

	const unsigned char * data = (const unsigned char *)key;

	while(len >= 4)
	{
		unsigned int k = *(unsigned int *)data;

		k *= m;
		k ^= k >> r;
		k *= m;

		h *= m;
		h ^= k;

		data += 4;
		len -= 4;
	}

	// Handle the last few bytes of the input array

	switch(len)
	{
	case 3: h ^= data[2] << 16;
	case 2: h ^= data[1] << 8;
	case 1: h ^= data[0];
			h *= m;
	};

	// Do a few final mixes of the hash to ensure the last few
	// bytes are well-incorporated.

	h ^= h >> 13;
	h *= m;
	h ^= h >> 15;

	return h;
}

unsigned int hash_of(const char* what, int what_length)
{
	return MurmurHash2(what, what_length, 0xDEADC0DE);
}

unsigned int hash_of(const std::string& what)
{
	return MurmurHash2(what.c_str(), what.size(), 0xDEADC0DE);
}

template<char... Str>
struct _tostring;

template<char C0, char... Str>
struct _tostring<C0, Str...>
{
	inline static void _(std::string& s)
	{
		s += C0;
		_tostring<Str...>::_(s);
	}
};

template<>
struct _tostring<>
{
	inline static void _(std::string&) { }
};

class atom_base
{

	std::string m_str;

	unsigned int m_hash;

 public:

	atom_base(std::string&& str) : m_str(str), m_hash(hash_of(m_str))
	{
	}

	unsigned int hash() const
	{
		return m_hash;
	}

	const std::string& value() const
	{
		return m_str;
	}

};

/*
template<char... Str>
class atom : atom_base
{
	static std::string to_string()
	{
		std::string result;
		_tostring<Str...>::_(result);
		return result;
	}

 public:

	atom() : atom_base(to_string()) { }

};
*/

/*
bool operator==(const atom& lhs, const atom& rhs)
{
	return (lhs.hash() == rhs.hash()) && (lhs.value() == rhs.value());
}

bool operator!=(const atom& lhs, const atom& rhs)
{
	return !(lhs == rhs);
}

bool operator!=(const atom& lhs, const std::string& rhs)
{
	return lhs.value() == rhs;
}

bool operator!=(const std::string& lhs, const atom& rhs)
{
	return lhs == rhs.value();
}
*/

// template<char...>
// atom<Str...> operator "" _atom();

template<char... Str>
class atom : public atom_base
{
	static std::string to_string()
	{
		std::string result;
		_tostring<Str...>::_(result);
		return result;
	}

 public:

	atom() : atom_base(to_string()) { }

};

void test__atom()
{

	CPPA_TEST(test__atom);

	atom<'f','o','o'>  a1;

	cout << "a1 = " << a1.value() << endl;

//	atom<"foobar"> a1;

//	CPPA_CHECK(a1 == a3);

}
<commit_msg>atoms... not<commit_after>#include <string>
#include <typeinfo>
#include <iostream>

#include "cppa/test.hpp"
#include "cppa/util.hpp"

using std::cout;
using std::endl;

using namespace cppa;
using namespace cppa::util;

unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
{
	static_assert(sizeof(int) == 4,
				  "MurmurHash2 requires sizeof(int) == 4");

	// 'm' and 'r' are mixing constants generated offline.
	// They're not really 'magic', they just happen to work well.

	const unsigned int m = 0x5bd1e995;
	const int r = 24;

	// Initialize the hash to a 'random' value

	unsigned int h = seed ^ len;

	// Mix 4 bytes at a time into the hash

	const unsigned char * data = (const unsigned char *)key;

	while(len >= 4)
	{
		unsigned int k = *(unsigned int *)data;

		k *= m;
		k ^= k >> r;
		k *= m;

		h *= m;
		h ^= k;

		data += 4;
		len -= 4;
	}

	// Handle the last few bytes of the input array

	switch(len)
	{
	case 3: h ^= data[2] << 16;
	case 2: h ^= data[1] << 8;
	case 1: h ^= data[0];
			h *= m;
	};

	// Do a few final mixes of the hash to ensure the last few
	// bytes are well-incorporated.

	h ^= h >> 13;
	h *= m;
	h ^= h >> 15;

	return h;
}

unsigned int hash_of(const char* what, int what_length)
{
	return MurmurHash2(what, what_length, 0x15091984);
}

unsigned int hash_of(const std::string& what)
{
	return MurmurHash2(what.c_str(), what.size(), 0x15091984);
}

template<char... Str>
struct _tostring;

template<char C0, char... Str>
struct _tostring<C0, Str...>
{
	inline static void _(std::string& s)
	{
		s += C0;
		_tostring<Str...>::_(s);
	}
};

template<>
struct _tostring<>
{
	inline static void _(std::string&) { }
};

class atom_base
{

	std::string m_str;

	unsigned int m_hash;

 public:

	atom_base(std::string&& str) : m_str(str), m_hash(hash_of(m_str))
	{
	}

	atom_base(atom_base&& rval) : m_str(std::move(rval.m_str)), m_hash(hash_of(m_str))
	{
	}

	unsigned int hash() const
	{
		return m_hash;
	}

	const std::string& value() const
	{
		return m_str;
	}

};

bool operator==(const atom_base& lhs, const atom_base& rhs)
{
	return (lhs.hash() == rhs.hash()) && (lhs.value() == rhs.value());
}

bool operator!=(const atom_base& lhs, const atom_base& rhs)
{
	return !(lhs == rhs);
}

bool operator!=(const atom_base& lhs, const std::string& rhs)
{
	return lhs.value() == rhs;
}

bool operator!=(const std::string& lhs, const atom_base& rhs)
{
	return lhs == rhs.value();
}

// template<char...>
// atom<Str...> operator "" _atom();

template<char... Str>
class atom : public atom_base
{
	static std::string to_string()
	{
		std::string result;
		_tostring<Str...>::_(result);
		return result;
	}

 public:

	atom() : atom_base(to_string()) { }
	atom(atom&& rval) : atom_base(rval) { }

};

void test__atom()
{

	CPPA_TEST(test__atom);

	atom<'f','o','o'>  a1;
	atom_base a2("foo");
	atom_base a3 = atom<'a','b','c'>();

	CPPA_CHECK(a1 == a2);
	CPPA_CHECK(a1 != a3);

//	atom<"foobar"> a1;

//	CPPA_CHECK(a1 == a3);

}
<|endoftext|>


<commit_before>#include <stdio.h> 				//׼ͷļ
#include <stdlib.h>				//׼ͷļ

#define LIST_INIT_SIZE 100		//̬ʵֵԱĳʼС
#define LISTINCREMENT 10		//ÿζ̬ӵĴС

#define OVERFLOW -1		//Խ
#define FALSE 0			//ʧ
#define OK 1			//ɹ

//̬ʵֵԱݽṹ
typedef struct{
	int *elem;		//ÿԱӦĶ̬׵ַַ
	int length; 	//Աǰĳ
	int listsize;		//ԱĴС
}SqList;

//ʼһյԱ
int InitList_Sq(SqList &L){

	//̬
	L.elem=(int*)malloc(LIST_INIT_SIZE*sizeof(int));

	if (!L.elem) return OVERFLOW; 				//ʧ

	L.length=0;									//ձĳΪ0
	L.listsize=LIST_INIT_SIZE; 						//ʼ洢

	return OK;									//سʼɹ
}//InitList_Sq 㷨 2.3

//˳Lеiλ֮ǰµԪe
int ListInsert_Sq(SqList &L,int i, int e){

	//жiֵǷϷ 1<=i<=L.length+1
	if (i<1||i>L.length+1) return OVERFLOW;

	//ǰ洢ռӷ
	if (L.length>=L.listsize){

		int * newbase=(int *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(int));

		if (!newbase) return OVERFLOW;		//ʧ

		L.elem=newbase;						//µĵַ
		L.listsize+=LISTINCREMENT; 			//ԱĴС
	}

	int *q=&(L.elem[i-1]);		//Ҫλ
	for (int *p=&(L.elem[L.length-1]); p>=q; p--){
		*(p+1)=*p;				//λüԪغһλ
	}

	*q=e;			//e
	++L.length;		//+1

	return OK;
}

//ԱLɾiԪأeֵ
int ListDelete_Sq(SqList &L,int i,int &e){

	if (i<1||i>L.length) return OVERFLOW;		// iȡֵΧΪ 1<=i<=L.length

	int *p=&(L.elem[i-1]);			//pΪɾԪ

	e=*p;							//eرɾԪ

	int *q=&(L.elem[L.length-1]); 	//βԪ  //  int *q=L.elem+L.length

	for (++p; p<=q; ++p){

		*(p-1)=*p;					//iԪԺԪͳͳǰƶһ ܹƶ n-i
	}

	--L.length;						//-1

	return OK;
}

int LocateElem(SqList &L,int e,int &i){

	for (int j=0; j<L.length; ++j){

		if (e==L.elem[j]){

			i=j+1;
			return OK;
		}
	}

	return FALSE;
}

//ԪرȽϺ
int compare(int p,int e){
	return p==e;
} //Compare

//Աвe compareԪصλ δҵ򷵻0
int LocateElem_Sq(SqList &L,int e,int (* compare)(int,int)){

	int i=1; 			//һԪصλ

	int *p=L.elem;		//һԪصָ

	while (i<=L.length&&!(*compare)(*p++,e)) ++i;		//ɨԱ  һ  ܺã

	if (i<=L.length) return i;			//ڷ λ
	else FALSE;							//ڷʧ
} //LocateElem_Sq

int main(){

	//һ ʵֵԱ
	SqList L;

	//ʼԱ
	InitList_Sq(L);

	//Բ200
	for (int i=0; i<200; i++){

		ListInsert_Sq(L,i+1,i);

		printf("%d %d \n",L.elem[i],L.length);
	}

	// ԱɾһԪ λ1
	int e;
	ListDelete_Sq(L,1,e);

	//ɾԪ
	printf("%d\n",e);

	//ӦɾԱ
	for (int i=0; i<L.length; i++){

		printf("%d %d\n",L.elem[i],i+1);
	}

	//Աв eԪ
	int i=LocateElem_Sq(L,78,compare);

	//ҽ
	printf("%d\n",i);
}
<commit_msg>fix-linear-list-locate-return-bug<commit_after>#include <stdio.h> 				//׼ͷļ
#include <stdlib.h>				//׼ͷļ

#define LIST_INIT_SIZE 100		//̬ʵֵԱĳʼС
#define LISTINCREMENT 10		//ÿζ̬ӵĴС

#define OVERFLOW -1		//Խ
#define FALSE 0			//ʧ
#define OK 1			//ɹ

//̬ʵֵԱݽṹ
typedef struct{
	int *elem;		//ÿԱӦĶ̬׵ַַ
	int length; 	//Աǰĳ
	int listsize;		//ԱĴС
}SqList;

//ʼһյԱ
int InitList_Sq(SqList &L){

	//̬
	L.elem=(int*)malloc(LIST_INIT_SIZE*sizeof(int));

	if (!L.elem) return OVERFLOW; 				//ʧ

	L.length=0;									//ձĳΪ0
	L.listsize=LIST_INIT_SIZE; 						//ʼ洢

	return OK;									//سʼɹ
}//InitList_Sq 㷨 2.3

//˳Lеiλ֮ǰµԪe
int ListInsert_Sq(SqList &L,int i, int e){

	//жiֵǷϷ 1<=i<=L.length+1
	if (i<1||i>L.length+1) return OVERFLOW;

	//ǰ洢ռӷ
	if (L.length>=L.listsize){

		int * newbase=(int *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(int));

		if (!newbase) return OVERFLOW;		//ʧ

		L.elem=newbase;						//µĵַ
		L.listsize+=LISTINCREMENT; 			//ԱĴС
	}

	int *q=&(L.elem[i-1]);		//Ҫλ
	for (int *p=&(L.elem[L.length-1]); p>=q; p--){
		*(p+1)=*p;				//λüԪغһλ
	}

	*q=e;			//e
	++L.length;		//+1

	return OK;
}

//ԱLɾiԪأeֵ
int ListDelete_Sq(SqList &L,int i,int &e){

	if (i<1||i>L.length) return OVERFLOW;		// iȡֵΧΪ 1<=i<=L.length

	int *p=&(L.elem[i-1]);			//pΪɾԪ

	e=*p;							//eرɾԪ

	int *q=&(L.elem[L.length-1]); 	//βԪ  //  int *q=L.elem+L.length

	for (++p; p<=q; ++p){

		*(p-1)=*p;					//iԪԺԪͳͳǰƶһ ܹƶ n-i
	}

	--L.length;						//-1

	return OK;
}

int LocateElem(SqList &L,int e,int &i){

	for (int j=0; j<L.length; ++j){

		if (e==L.elem[j]){

			i=j+1;
			return OK;
		}
	}

	return FALSE;
}

//ԪرȽϺ
int compare(int p,int e){
	return p==e;
} //Compare

//Աвe compareԪصλ δҵ򷵻0
int LocateElem_Sq(SqList &L,int e,int (* compare)(int,int)){

	int i=1; 			//һԪصλ

	int *p=L.elem;		//һԪصָ

	while (i<=L.length&&!(*compare)(*p++,e)) ++i;		//ɨԱ  һ  ܺã

	if (i<=L.length) return i;			//ڷ λ
	else return FALSE;					//ڷʧ
} //LocateElem_Sq

int main(){

	//һ ʵֵԱ
	SqList L;

	//ʼԱ
	InitList_Sq(L);

	//Բ200
	for (int i=0; i<200; i++){

		ListInsert_Sq(L,i+1,i);

		printf("%d %d \n",L.elem[i],L.length);
	}

	// ԱɾһԪ λ1
	int e;
	ListDelete_Sq(L,1,e);

	//ɾԪ
	printf("%d\n",e);

	//ӦɾԱ
	for (int i=0; i<L.length; i++){

		printf("%d %d\n",L.elem[i],i+1);
	}

	//Աв eԪ
	int i=LocateElem_Sq(L,78,compare);

	//ҽ
	printf("%d\n",i);
}
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

using namespace std;

#include "config.h"

#include "common/ConfUtils.h"
#include "common/common_init.h"
#include "auth/Crypto.h"
#include "auth/Auth.h"
#include "auth/KeyRing.h"

void usage()
{
  cout << " usage: [--create-keyring] [--gen-key] [--name=<name>] [--caps=<filename>] [--list] [--print-key] <filename>" << std::endl;
  exit(1);
}

int main(int argc, const char **argv)
{
  vector<const char*> args;
  argv_to_vec(argc, argv, args);
  env_to_vec(args);
  DEFINE_CONF_VARS(usage);
  common_init(args, "osdmaptool", false, false);

  const char *me = argv[0];

  const char *fn = 0;
  bool gen_key = false;
  bool list = false;
  bool print_key = false;
  bool create_keyring = false;
  const char *name = "";
  const char *caps_fn = NULL;
  const char *import_keyring = NULL;

  FOR_EACH_ARG(args) {
    if (CONF_ARG_EQ("gen-key", 'g')) {
      CONF_SAFE_SET_ARG_VAL(&gen_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("name", 'n')) {
      CONF_SAFE_SET_ARG_VAL(&name, OPT_STR);
    } else if (CONF_ARG_EQ("list", 'l')) {
      CONF_SAFE_SET_ARG_VAL(&list, OPT_BOOL);
    } else if (CONF_ARG_EQ("caps", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&caps_fn, OPT_STR);
    } else if (CONF_ARG_EQ("print-key", 'p')) {
      CONF_SAFE_SET_ARG_VAL(&print_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("create-keyring", 'c')) {
      CONF_SAFE_SET_ARG_VAL(&create_keyring, OPT_BOOL);
    } else if (CONF_ARG_EQ("import-keyring", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&import_keyring, OPT_STR);
    } else if (!fn) {
      fn = args[i];
    } else
      usage();
  }
  if (!fn) {
    cerr << me << ": must specify filename" << std::endl;
    usage();
  }

  bool modified = false;
  KeyRing keyring;
  string s = name;
  EntityName ename;
  ename.from_str(s);

  if (caps_fn) {
    if (!name || !(*name)) {
      cerr << "can't specify caps without name" << std::endl;
      exit(1);
    }
  }

  bufferlist bl;
  int r = 0;
  if (create_keyring) {
    cout << "creating " << fn << std::endl;
  } else {
    r = bl.read_file(fn, true);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = bl.begin();
	::decode(keyring, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << fn << std::endl;
	exit(1);
      }
    } else {
      cerr << "can't open " << fn << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  }

  if (gen_key) {
    EntityAuth eauth;
    eauth.key.create(CEPH_CRYPTO_AES);
    keyring.add(ename, eauth);
    modified = true;
  } else if (list) {
    keyring.print(cout);
  } else if (print_key) {
    CryptoKey key;
    if (keyring.get_secret(ename, key)) {
      string a;
      key.encode_base64(a);
      cout << a << std::endl;
    } else {
      cerr << "entity " << ename << " not found" << std::endl;
    }
  } else if (import_keyring) {
    KeyRing other;
    bufferlist obl;
    int r = obl.read_file(import_keyring);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = obl.begin();
	::decode(other, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << import_keyring << std::endl;
	exit(1);
      }

      cout << "importing contents of " << import_keyring << " into " << fn << std::endl;
      //other.print(cout);
      keyring.import(other);
      modified = true;

    } else {
      cerr << "can't open " << import_keyring << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  } else {
    cerr << "no command specified" << std::endl;
    usage();
  }

  if (caps_fn) {
    ConfFile *cf = new ConfFile(caps_fn);
    if (!cf->parse()) {
      cerr << "could not parse caps file " << caps_fn << std::endl;
      exit(1);
    }
    map<string, bufferlist> caps;
    const char *key_names[] = { "mon", "osd", "mds", NULL };
    for (int i=0; key_names[i]; i++) {
      char *val;
      cf->read("global", key_names[i], &val, NULL);
      if (val) {
        bufferlist bl;
        ::encode(val, bl);
        string s(key_names[i]);
        caps[s] = bl;
        free(val);
      }
    }
    keyring.set_caps(ename, caps);
    modified = true;
  }

  if (modified) {
    bufferlist bl;
    ::encode(keyring, bl);
    r = bl.write_file(fn);
    if (r < 0) {
      cerr << "could not write " << fn << std::endl;
    }
    //cout << "wrote " << bl.length() << " bytes to " << fn << std::endl;
  }

  return 0;
}
<commit_msg>authtool: only create keyring if --create-keyring (or -c)<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

using namespace std;

#include "config.h"

#include "common/ConfUtils.h"
#include "common/common_init.h"
#include "auth/Crypto.h"
#include "auth/Auth.h"
#include "auth/KeyRing.h"

void usage()
{
  cout << " usage: [--create-keyring] [--gen-key] [--name=<name>] [--caps=<filename>] [--list] [--print-key] <filename>" << std::endl;
  exit(1);
}

int main(int argc, const char **argv)
{
  vector<const char*> args;
  argv_to_vec(argc, argv, args);
  env_to_vec(args);
  DEFINE_CONF_VARS(usage);
  common_init(args, "osdmaptool", false, false);

  const char *me = argv[0];

  const char *fn = 0;
  bool gen_key = false;
  bool list = false;
  bool print_key = false;
  bool create_keyring = false;
  const char *name = "";
  const char *caps_fn = NULL;
  const char *import_keyring = NULL;

  FOR_EACH_ARG(args) {
    if (CONF_ARG_EQ("gen-key", 'g')) {
      CONF_SAFE_SET_ARG_VAL(&gen_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("name", 'n')) {
      CONF_SAFE_SET_ARG_VAL(&name, OPT_STR);
    } else if (CONF_ARG_EQ("list", 'l')) {
      CONF_SAFE_SET_ARG_VAL(&list, OPT_BOOL);
    } else if (CONF_ARG_EQ("caps", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&caps_fn, OPT_STR);
    } else if (CONF_ARG_EQ("print-key", 'p')) {
      CONF_SAFE_SET_ARG_VAL(&print_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("create-keyring", 'c')) {
      CONF_SAFE_SET_ARG_VAL(&create_keyring, OPT_BOOL);
    } else if (CONF_ARG_EQ("import-keyring", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&import_keyring, OPT_STR);
    } else if (!fn) {
      fn = args[i];
    } else
      usage();
  }
  if (!fn) {
    cerr << me << ": must specify filename" << std::endl;
    usage();
  }

  bool modified = false;
  KeyRing keyring;
  string s = name;
  EntityName ename;
  ename.from_str(s);

  if (caps_fn) {
    if (!name || !(*name)) {
      cerr << "can't specify caps without name" << std::endl;
      exit(1);
    }
  }

  bufferlist bl;
  int r = 0;
  if (create_keyring) {
    cout << "creating " << fn << std::endl;
    modified = true;
  } else {
    r = bl.read_file(fn, true);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = bl.begin();
	::decode(keyring, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << fn << std::endl;
	exit(1);
      }
    } else {
      cerr << "can't open " << fn << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  }

  if (gen_key) {
    EntityAuth eauth;
    eauth.key.create(CEPH_CRYPTO_AES);
    keyring.add(ename, eauth);
    modified = true;
  } else if (list) {
    keyring.print(cout);
  } else if (print_key) {
    CryptoKey key;
    if (keyring.get_secret(ename, key)) {
      string a;
      key.encode_base64(a);
      cout << a << std::endl;
    } else {
      cerr << "entity " << ename << " not found" << std::endl;
    }
  } else if (import_keyring) {
    KeyRing other;
    bufferlist obl;
    int r = obl.read_file(import_keyring);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = obl.begin();
	::decode(other, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << import_keyring << std::endl;
	exit(1);
      }

      cout << "importing contents of " << import_keyring << " into " << fn << std::endl;
      //other.print(cout);
      keyring.import(other);
      modified = true;

    } else {
      cerr << "can't open " << import_keyring << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  } else {
    cerr << "no command specified" << std::endl;
    usage();
  }

  if (caps_fn) {
    ConfFile *cf = new ConfFile(caps_fn);
    if (!cf->parse()) {
      cerr << "could not parse caps file " << caps_fn << std::endl;
      exit(1);
    }
    map<string, bufferlist> caps;
    const char *key_names[] = { "mon", "osd", "mds", NULL };
    for (int i=0; key_names[i]; i++) {
      char *val;
      cf->read("global", key_names[i], &val, NULL);
      if (val) {
        bufferlist bl;
        ::encode(val, bl);
        string s(key_names[i]);
        caps[s] = bl;
        free(val);
      }
    }
    keyring.set_caps(ename, caps);
    modified = true;
  }

  if (modified) {
    bufferlist bl;
    ::encode(keyring, bl);
    r = bl.write_file(fn);
    if (r < 0) {
      cerr << "could not write " << fn << std::endl;
    }
    //cout << "wrote " << bl.length() << " bytes to " << fn << std::endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>
#include "InverseKinematicsStudy.h"
#include "OpenSenseUtilities.h"
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/TimeSeriesTable.h>
#include <OpenSim/Common/TableSource.h>
#include <OpenSim/Common/STOFileAdapter.h>
#include <OpenSim/Common/TRCFileAdapter.h>
#include <OpenSim/Common/Reporter.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Simulation/Model/PhysicalOffsetFrame.h>
#include <OpenSim/Simulation/InverseKinematicsSolver.h>
#include <OpenSim/Simulation/OrientationsReference.h>
#include "ExperimentalMarker.h"
#include "ExperimentalFrame.h"

using namespace OpenSim;
using namespace SimTK;
using namespace std;

InverseKinematicsStudy::InverseKinematicsStudy()
{
    constructProperties();
}

InverseKinematicsStudy::InverseKinematicsStudy(const std::string& setupFile)
    : Object(setupFile, true)
{
    constructProperties();
    updateFromXMLDocument();
}

InverseKinematicsStudy::~InverseKinematicsStudy()
{
}

void InverseKinematicsStudy::constructProperties()
{
    constructProperty_accuracy(1e-6);
    constructProperty_constraint_weight(Infinity);
    Array<double> range{ Infinity, 2};
    constructProperty_time_range(range);

    constructProperty_base_imu_label("");
    constructProperty_base_heading_axis("z");

    constructProperty_model_file_name("");
    constructProperty_marker_file_name("");
    constructProperty_orientations_file_name("");

    constructProperty_results_directory("");
}

void InverseKinematicsStudy::
    previewExperimentalData(const TimeSeriesTableVec3& markers,
                const TimeSeriesTable_<SimTK::Rotation>& orientations) const
{
    Model previewWorld;

    // Load the marker data into a TableSource that has markers
    // as its output which each markers occupying its own channel
    TableSourceVec3* markersSource = new TableSourceVec3(markers);
    // Add the markersSource Component to the model
    previewWorld.addComponent(markersSource);

    // Get the underlying Table backing the the marker Source so we
    // know how many markers we have and their names
    const auto& markerData = markersSource->getTable();
    auto& times = markerData.getIndependentColumn();

    auto startEnd = getTimeRangeInUse(times);

    // Create an ExperimentalMarker Component for every column in the markerData
    for (int i = 0; i < int(markerData.getNumColumns()) ; ++i) {
        auto marker = new ExperimentalMarker();
        marker->setName(markerData.getColumnLabel(i));

        // markers are owned by the model
        previewWorld.addComponent(marker);
        // the time varying location of the marker comes from the markersSource
        // Component
        marker->updInput("location_in_ground").connect(
            markersSource->getOutput("column").getChannel(markerData.getColumnLabel(i)));
    }

    previewWorld.setUseVisualizer(true);
    SimTK::State& state = previewWorld.initSystem();
    state.updTime() = times[0];

    previewWorld.realizePosition(state);
    previewWorld.getVisualizer().show(state);

    char c;
    std::cout << "press any key to visualize experimental marker data ..." << std::endl;
    std::cin >> c;

    for (size_t j =startEnd[0]; j <= startEnd[1]; j=j+10) {
        std::cout << "time: " << times[j] << "s" << std::endl;
        state.setTime(times[j]);
        previewWorld.realizePosition(state);
        previewWorld.getVisualizer().show(state);
    }
}

void InverseKinematicsStudy::
runInverseKinematicsWithOrientationsFromFile(Model& model,
    const std::string& orientationsFileName,
    bool visualizeResults)
{
    // Add a reporter to get IK computed coordinate values out
    TableReporter* ikReporter = new TableReporter();
    ikReporter->setName("ik_reporter");
    auto coordinates = model.updComponentList<Coordinate>();
    std::vector<std::string> transCoordNames;

    // Hookup reporter inputs to the individual coordinate outputs
    // and keep track of coordinates that are translations
    for (auto& coord : coordinates) {
        ikReporter->updInput("inputs").connect(
            coord.getOutput("value"), coord.getName());
        if (coord.getMotionType() == Coordinate::Translational) {
            transCoordNames.push_back(coord.getName());
            coord.set_locked(true);
        }
    }
    model.addComponent(ikReporter);

    TimeSeriesTable_<SimTK::Quaternion> quatTable =
        STOFileAdapter_<SimTK::Quaternion>::readFile(orientationsFileName);
    std::cout << "Loading orientations as quaternions from "
        << orientationsFileName << std::endl;

    auto startEnd = getTimeRangeInUse(quatTable.getIndependentColumn());

    const auto axis_string = IO::Lowercase(get_base_heading_axis());

    int axis = (axis_string == "x" ? 0 :
                                    ((axis_string == "y") ? 1 : 2) );
    SimTK::CoordinateAxis heading{ axis };

    cout << "Heading correction for base '" << get_base_imu_label()
        << "' along its '" << axis_string << "' axis." << endl;

    TimeSeriesTable_<SimTK::Rotation> orientationsData =
        OpenSenseUtilities::convertQuaternionsToRotations(quatTable,
             startEnd, get_base_imu_label(), heading);

    OrientationsReference oRefs(orientationsData);
    MarkersReference mRefs{};

    SimTK::Array_<CoordinateReference> coordinateReferences;

    // visualize for debugging
    if (visualizeResults)
        model.setUseVisualizer(true);
    SimTK::State& s0 = model.initSystem();

    double t0 = s0.getTime();

    // create the solver given the input data
    const double accuracy = 1e-4;
    InverseKinematicsSolver ikSolver(model, mRefs, oRefs,
        coordinateReferences);
    ikSolver.setAccuracy(accuracy);

    auto& times = oRefs.getTimes();

    s0.updTime() = times[0];
    ikSolver.assemble(s0);
    if (visualizeResults) {
        model.getVisualizer().show(s0);
        model.getVisualizer().getSimbodyVisualizer().setShowSimTime(true);
    }
    for (auto time : times) {
        s0.updTime() = time;
        ikSolver.track(s0);
        if (visualizeResults)
            model.getVisualizer().show(s0);
        else
            cout << "Solved frame at time: " << time << endl;
        // realize to report to get reporter to pull values from model
        model.realizeReport(s0);
    }

    auto report = ikReporter->getTable();

    auto eix = orientationsFileName.rfind("_");
    if (eix == std::string::npos) {
        eix = orientationsFileName.rfind(".");
    }
    auto stix = orientationsFileName.rfind("/") + 1;

    IO::makeDir(get_results_directory());
    std::string outName = "ik_" + orientationsFileName.substr(stix, eix-stix);
    std::string outputFile = get_results_directory() + "/" + outName;

    // Convert to degrees to compare with marker-based IK
    // but ignore translational coordinates
    for (size_t i = 0; i < report.getNumColumns(); ++i) {
        auto it = find( transCoordNames.begin(), transCoordNames.end(),
                        report.getColumnLabel(i) );
        if (it == transCoordNames.end()) { // not found = not translational
            auto repVec = report.updDependentColumnAtIndex(i);
            repVec *= SimTK::Real(SimTK_RTD);
        }
    }

    report.updTableMetaData().setValueForKey<string>("name", outName);
    report.updTableMetaData().setValueForKey<size_t>("nRows", report.getNumRows());
    // getNumColumns returns the number of dependent columns, but Storage expects time
    report.updTableMetaData().setValueForKey<size_t>("nColumns", report.getNumColumns()+1);
    report.updTableMetaData().setValueForKey<string>("inDegrees","yes");

    STOFileAdapter_<double>::write(report, outputFile + ".mot");

    std::cout << "Wrote IK with IMU tracking results to: '" <<
        outputFile << "'." << std::endl;
}

// main driver
bool InverseKinematicsStudy::run(bool visualizeResults)
{

    Model modelWithIMUs(get_model_file_name());

    runInverseKinematicsWithOrientationsFromFile(modelWithIMUs,
                                                 get_orientations_file_name(),
                                                 visualizeResults);

    return true;
}

SimTK::Array_<int> InverseKinematicsStudy::getTimeRangeInUse(
                                const std::vector<double>& times ) const
{
    int nt = static_cast<int>(times.size());
    int startIx = 0;
    int endIx = nt-1;

    for (int i = 0; i < nt; ++i) {
        if (times[i] <= get_time_range(0)) {
            startIx = i;
        }
        else {
            break;
        }
    }

    for (int i = nt - 1; i > 0; --i) {
        if (times[i] >= get_time_range(1)) {
            endIx= i;
        }
        else {
            break;
        }
    }
    SimTK::Array_<int> retArray;
    retArray.push_back(startIx);
    retArray.push_back(endIx);
    return retArray;
}

TimeSeriesTable_<SimTK::Vec3>
    InverseKinematicsStudy::loadMarkersFile(const std::string& markerFile)
{
    auto markers = TRCFileAdapter::readFile(markerFile);
    std::cout << markerFile << " loaded " << markers.getNumColumns() << " markers "
        << " and " << markers.getNumRows() << " rows of data." << std::endl;

    if (markers.hasTableMetaDataKey("Units")) {
        std::cout << markerFile << " has Units meta data." << std::endl;
        auto& value = markers.getTableMetaData().getValueForKey("Units");
        std::cout << markerFile << " Units are " << value.getValue<std::string>() << std::endl;
        if (value.getValue<std::string>() == "mm") {
            std::cout << "Marker data in mm, converting to m." << std::endl;
            for (size_t i = 0; i < markers.getNumRows(); ++i) {
                markers.updRowAtIndex(i) *= 0.001;
            }
            markers.updTableMetaData().removeValueForKey("Units");
            markers.updTableMetaData().setValueForKey<std::string>("Units", "m");
        }
    }
    auto& value = markers.getTableMetaData().getValueForKey("Units");
    std::cout << markerFile << " Units are " << value.getValue<std::string>() << std::endl;
    return markers;
}<commit_msg>If the model is set on the Study use it instead of reading in from file.<commit_after>
#include "InverseKinematicsStudy.h"
#include "OpenSenseUtilities.h"
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/TimeSeriesTable.h>
#include <OpenSim/Common/TableSource.h>
#include <OpenSim/Common/STOFileAdapter.h>
#include <OpenSim/Common/TRCFileAdapter.h>
#include <OpenSim/Common/Reporter.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Simulation/Model/PhysicalOffsetFrame.h>
#include <OpenSim/Simulation/InverseKinematicsSolver.h>
#include <OpenSim/Simulation/OrientationsReference.h>
#include "ExperimentalMarker.h"
#include "ExperimentalFrame.h"

using namespace OpenSim;
using namespace SimTK;
using namespace std;

InverseKinematicsStudy::InverseKinematicsStudy()
{
    constructProperties();
}

InverseKinematicsStudy::InverseKinematicsStudy(const std::string& setupFile)
    : Object(setupFile, true)
{
    constructProperties();
    updateFromXMLDocument();
}

InverseKinematicsStudy::~InverseKinematicsStudy()
{
}

void InverseKinematicsStudy::constructProperties()
{
    constructProperty_accuracy(1e-6);
    constructProperty_constraint_weight(Infinity);
    Array<double> range{ Infinity, 2};
    constructProperty_time_range(range);

    constructProperty_base_imu_label("");
    constructProperty_base_heading_axis("z");

    constructProperty_model_file_name("");
    constructProperty_marker_file_name("");
    constructProperty_orientations_file_name("");

    constructProperty_results_directory("");
}

void InverseKinematicsStudy::
    previewExperimentalData(const TimeSeriesTableVec3& markers,
                const TimeSeriesTable_<SimTK::Rotation>& orientations) const
{
    Model previewWorld;

    // Load the marker data into a TableSource that has markers
    // as its output which each markers occupying its own channel
    TableSourceVec3* markersSource = new TableSourceVec3(markers);
    // Add the markersSource Component to the model
    previewWorld.addComponent(markersSource);

    // Get the underlying Table backing the the marker Source so we
    // know how many markers we have and their names
    const auto& markerData = markersSource->getTable();
    auto& times = markerData.getIndependentColumn();

    auto startEnd = getTimeRangeInUse(times);

    // Create an ExperimentalMarker Component for every column in the markerData
    for (int i = 0; i < int(markerData.getNumColumns()) ; ++i) {
        auto marker = new ExperimentalMarker();
        marker->setName(markerData.getColumnLabel(i));

        // markers are owned by the model
        previewWorld.addComponent(marker);
        // the time varying location of the marker comes from the markersSource
        // Component
        marker->updInput("location_in_ground").connect(
            markersSource->getOutput("column").getChannel(markerData.getColumnLabel(i)));
    }

    previewWorld.setUseVisualizer(true);
    SimTK::State& state = previewWorld.initSystem();
    state.updTime() = times[0];

    previewWorld.realizePosition(state);
    previewWorld.getVisualizer().show(state);

    char c;
    std::cout << "press any key to visualize experimental marker data ..." << std::endl;
    std::cin >> c;

    for (size_t j =startEnd[0]; j <= startEnd[1]; j=j+10) {
        std::cout << "time: " << times[j] << "s" << std::endl;
        state.setTime(times[j]);
        previewWorld.realizePosition(state);
        previewWorld.getVisualizer().show(state);
    }
}

void InverseKinematicsStudy::
runInverseKinematicsWithOrientationsFromFile(Model& model,
    const std::string& orientationsFileName,
    bool visualizeResults)
{
    // Add a reporter to get IK computed coordinate values out
    TableReporter* ikReporter = new TableReporter();
    ikReporter->setName("ik_reporter");
    auto coordinates = model.updComponentList<Coordinate>();
    std::vector<std::string> transCoordNames;

    // Hookup reporter inputs to the individual coordinate outputs
    // and keep track of coordinates that are translations
    for (auto& coord : coordinates) {
        ikReporter->updInput("inputs").connect(
            coord.getOutput("value"), coord.getName());
        if (coord.getMotionType() == Coordinate::Translational) {
            transCoordNames.push_back(coord.getName());
            coord.set_locked(true);
        }
    }
    model.addComponent(ikReporter);

    TimeSeriesTable_<SimTK::Quaternion> quatTable =
        STOFileAdapter_<SimTK::Quaternion>::readFile(orientationsFileName);
    std::cout << "Loading orientations as quaternions from "
        << orientationsFileName << std::endl;

    auto startEnd = getTimeRangeInUse(quatTable.getIndependentColumn());

    const auto axis_string = IO::Lowercase(get_base_heading_axis());

    int axis = (axis_string == "x" ? 0 :
                                    ((axis_string == "y") ? 1 : 2) );
    SimTK::CoordinateAxis heading{ axis };

    cout << "Heading correction for base '" << get_base_imu_label()
        << "' along its '" << axis_string << "' axis." << endl;

    TimeSeriesTable_<SimTK::Rotation> orientationsData =
        OpenSenseUtilities::convertQuaternionsToRotations(quatTable,
             startEnd, get_base_imu_label(), heading);

    OrientationsReference oRefs(orientationsData);
    MarkersReference mRefs{};

    SimTK::Array_<CoordinateReference> coordinateReferences;

    // visualize for debugging
    if (visualizeResults)
        model.setUseVisualizer(true);
    SimTK::State& s0 = model.initSystem();

    double t0 = s0.getTime();

    // create the solver given the input data
    const double accuracy = 1e-4;
    InverseKinematicsSolver ikSolver(model, mRefs, oRefs,
        coordinateReferences);
    ikSolver.setAccuracy(accuracy);

    auto& times = oRefs.getTimes();

    s0.updTime() = times[0];
    ikSolver.assemble(s0);
    if (visualizeResults) {
        model.getVisualizer().show(s0);
        model.getVisualizer().getSimbodyVisualizer().setShowSimTime(true);
    }
    for (auto time : times) {
        s0.updTime() = time;
        ikSolver.track(s0);
        if (visualizeResults)
            model.getVisualizer().show(s0);
        else
            cout << "Solved frame at time: " << time << endl;
        // realize to report to get reporter to pull values from model
        model.realizeReport(s0);
    }

    auto report = ikReporter->getTable();

    auto eix = orientationsFileName.rfind("_");
    if (eix == std::string::npos) {
        eix = orientationsFileName.rfind(".");
    }
    auto stix = orientationsFileName.rfind("/") + 1;

    IO::makeDir(get_results_directory());
    std::string outName = "ik_" + orientationsFileName.substr(stix, eix-stix);
    std::string outputFile = get_results_directory() + "/" + outName;

    // Convert to degrees to compare with marker-based IK
    // but ignore translational coordinates
    for (size_t i = 0; i < report.getNumColumns(); ++i) {
        auto it = find( transCoordNames.begin(), transCoordNames.end(),
                        report.getColumnLabel(i) );
        if (it == transCoordNames.end()) { // not found = not translational
            auto repVec = report.updDependentColumnAtIndex(i);
            repVec *= SimTK::Real(SimTK_RTD);
        }
    }

    report.updTableMetaData().setValueForKey<string>("name", outName);
    report.updTableMetaData().setValueForKey<size_t>("nRows", report.getNumRows());
    // getNumColumns returns the number of dependent columns, but Storage expects time
    report.updTableMetaData().setValueForKey<size_t>("nColumns", report.getNumColumns()+1);
    report.updTableMetaData().setValueForKey<string>("inDegrees","yes");

    STOFileAdapter_<double>::write(report, outputFile + ".mot");

    std::cout << "Wrote IK with IMU tracking results to: '" <<
        outputFile << "'." << std::endl;
}

// main driver
bool InverseKinematicsStudy::run(bool visualizeResults)
{
    if (_model.empty()) {
        _model.reset(new Model(get_model_file_name()));
    }

    runInverseKinematicsWithOrientationsFromFile(*_model,
                                                 get_orientations_file_name(),
                                                 visualizeResults);

    return true;
}

SimTK::Array_<int> InverseKinematicsStudy::getTimeRangeInUse(
                                const std::vector<double>& times ) const
{
    int nt = static_cast<int>(times.size());
    int startIx = 0;
    int endIx = nt-1;

    for (int i = 0; i < nt; ++i) {
        if (times[i] <= get_time_range(0)) {
            startIx = i;
        }
        else {
            break;
        }
    }

    for (int i = nt - 1; i > 0; --i) {
        if (times[i] >= get_time_range(1)) {
            endIx= i;
        }
        else {
            break;
        }
    }
    SimTK::Array_<int> retArray;
    retArray.push_back(startIx);
    retArray.push_back(endIx);
    return retArray;
}

TimeSeriesTable_<SimTK::Vec3>
    InverseKinematicsStudy::loadMarkersFile(const std::string& markerFile)
{
    auto markers = TRCFileAdapter::readFile(markerFile);
    std::cout << markerFile << " loaded " << markers.getNumColumns() << " markers "
        << " and " << markers.getNumRows() << " rows of data." << std::endl;

    if (markers.hasTableMetaDataKey("Units")) {
        std::cout << markerFile << " has Units meta data." << std::endl;
        auto& value = markers.getTableMetaData().getValueForKey("Units");
        std::cout << markerFile << " Units are " << value.getValue<std::string>() << std::endl;
        if (value.getValue<std::string>() == "mm") {
            std::cout << "Marker data in mm, converting to m." << std::endl;
            for (size_t i = 0; i < markers.getNumRows(); ++i) {
                markers.updRowAtIndex(i) *= 0.001;
            }
            markers.updTableMetaData().removeValueForKey("Units");
            markers.updTableMetaData().setValueForKey<std::string>("Units", "m");
        }
    }
    auto& value = markers.getTableMetaData().getValueForKey("Units");
    std::cout << markerFile << " Units are " << value.getValue<std::string>() << std::endl;
    return markers;
}<|endoftext|>


<commit_before>/****************************************************************************

This file is part of the QtMediaHub project on http://www.gitorious.org.

Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).*
All rights reserved.

Contact:  Nokia Corporation (qt-info@nokia.com)**

You may use this file under the terms of the BSD license as follows:

"Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."

****************************************************************************/

#include "backend.h"
#include "plugins/qmhplugin/qmhplugin.h"

#include "qmh-config.h"
#include "rpc/rpcconnection.h"
#include "skin.h"

#ifdef QMH_AVAHI
#include "qavahiservicebrowsermodel.h"
#endif

#include <QDir>
#include <QString>
#include <QPluginLoader>
#include <QCoreApplication>
#include <QVariant>
#include <QFileSystemModel>
#include <QDesktopServices>
#include <QFileSystemWatcher>

#ifdef GL
#include <QGLFormat>
#endif

#include <QDebug>

Backend* Backend::pSelf = 0;

class BackendPrivate : public QObject
{
    Q_OBJECT
public:
    BackendPrivate(Backend *p)
        : QObject(p),
      #ifdef Q_OS_MAC
          platformOffset("/../../.."),
      #endif
          basePath(QCoreApplication::applicationDirPath() + platformOffset),
          // Use "large" instead of appName to fit freedesktop spec
          thumbnailPath(Config::value("thumbnail-path", QDir::homePath() + "/.thumbnails/" + qApp->applicationName() + "/")),
          inputIdleTimer(this),
          backendTranslator(0),
          logFile(qApp->applicationName().append(".log")),
          targetsModel(0),
          pSelf(p)
    {
        // TODO: check install prefix
        skinPaths << "/usr/share/qtmediahub/skins/";
        skinPaths << QDir::homePath() + "/.qtmediahub/skins/";
        QDir skinPath(Config::value("skins", QString(basePath % "/skins")));
        if (skinPath.exists())
            skinPaths << skinPath.absolutePath();

        pluginPath = QDir(Config::value("plugins", QString(basePath % "/plugins"))).absolutePath();
        resourcePath = QDir(Config::value("resources", QString(basePath % "/resources"))).absolutePath();

        inputIdleTimer.setInterval(Config::value("idle-timeout", 120)*1000);
        inputIdleTimer.setSingleShot(true);
        inputIdleTimer.start();

        connect(&inputIdleTimer, SIGNAL(timeout()), pSelf, SIGNAL(inputIdle()));

        logFile.open(QIODevice::Text|QIODevice::ReadWrite);
        log.setDevice(&logFile);

        connect(&resourcePathMonitor,
                SIGNAL(directoryChanged(const QString &)),
                this,
                SLOT(handleDirChanged(const QString &)));

        foreach (QString skinPath, skinPaths)
            resourcePathMonitor.addPath(skinPath);
        resourcePathMonitor.addPath(pluginPath);

        QFileInfo thumbnailFolderInfo(thumbnailPath);
        if (!thumbnailFolderInfo.exists()) {
            QDir dir;
            dir.mkpath(thumbnailFolderInfo.absoluteFilePath());
        }

        discoverSkins();
    }

    ~BackendPrivate()
    {
        delete backendTranslator;
        backendTranslator = 0;
        qDeleteAll(pluginTranslators.begin(), pluginTranslators.end());
    }

public slots:
    void handleDirChanged(const QString &dir);

public:
    void resetLanguage();
    void discoverSkins();
    void discoverEngines();

    QSet<QString> advertizedEngineRoles;

    QList<QMHPlugin*> advertizedEngines;
    QList<QMHPlugin*> allEngines;

    const QString platformOffset;

    const QString basePath;
    QString pluginPath;
    QString resourcePath;
    const QString thumbnailPath;

    QStringList skinPaths;
    QList<QObject *> skins;

    QTimer inputIdleTimer;
    QTranslator *backendTranslator;
    QList<QTranslator*> pluginTranslators;
    QFile logFile;
    QTextStream log;
    QFileSystemWatcher resourcePathMonitor;

    QAbstractItemModel *targetsModel;

#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    QNetworkConfigurationManager mgr;
    QNetworkSession *session;
#endif

    Backend *pSelf;
};

void BackendPrivate::handleDirChanged(const QString &dir)
{
    if(dir == pluginPath) {
        qWarning() << "Changes in plugin path, probably about to eat your poodle";
        discoverEngines();
    } else if(skinPaths.contains(dir)) {
        qWarning() << "Changes in skin path, repopulating skins";
        discoverSkins();
    }
}

void BackendPrivate::resetLanguage()
{
    static QString baseTranslationPath(basePath % "/translations/");
    const QString language = Backend::instance()->language();
    delete backendTranslator;
    backendTranslator = new QTranslator(this);
    backendTranslator->load(baseTranslationPath % language % ".qm");
    qApp->installTranslator(backendTranslator);

    qDeleteAll(pluginTranslators.begin(), pluginTranslators.end());

    foreach(QMHPlugin *plugin, allEngines) {
        QTranslator *pluginTranslator = new QTranslator(this);
        pluginTranslator->load(baseTranslationPath % plugin->role() % "_" % language % ".qm");
        pluginTranslators << pluginTranslator;
        qApp->installTranslator(pluginTranslator);
    }
}

void BackendPrivate::discoverSkins()
{
    skins.clear();

    foreach (QString skinPath, skinPaths) {
        QStringList potentialSkins = QDir(skinPath).entryList(QDir::Dirs | QDir::NoDotAndDotDot);

        foreach(const QString &currentPath, potentialSkins) {
            if(QFile(skinPath % "/" % currentPath % "/" % currentPath).exists()) {
                Skin *skin = new Skin(currentPath, skinPath % "/" % currentPath % "/");
                skins << skin;
            }
        }
    }

    qWarning() << "Available skins:";
    foreach(QObject *skin, skins)
        qWarning() << "\t" << qobject_cast<Skin*>(skin)->name();
}

void BackendPrivate::discoverEngines()
{
    foreach(const QString fileName, QDir(pluginPath).entryList(QDir::Files)) {
        QString qualifiedFileName(pluginPath % "/" % fileName);
        QPluginLoader pluginLoader(qualifiedFileName);

        if (!pluginLoader.load()) {
            qWarning() << tr("Cant load plugin: %1 returns %2").arg(qualifiedFileName).arg(pluginLoader.errorString());
            continue;
        }

        QMHPlugin *plugin = qobject_cast<QMHPlugin*>(pluginLoader.instance());
        if (!plugin)
            qWarning() << tr("Invalid QMH plugin present: %1").arg(qualifiedFileName);
        else if (!plugin->dependenciesSatisfied())
            qWarning() << tr("Can't meet dependencies for %1").arg(qualifiedFileName);
        else if (plugin->role() == "undefined")
            qWarning() << tr("Plugin %1 has an undefined role").arg(qualifiedFileName);
        else {
            plugin->setParent(this);
            allEngines << plugin;
            Backend::instance()->advertizeEngine(plugin);
        }
    }
    resetLanguage();
}

Backend::Backend(QObject *parent)
    : QObject(parent),
      d(new BackendPrivate(this))
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    // Set Internet Access Point
    QList<QNetworkConfiguration> activeConfigs = d->mgr.allConfigurations();
    if (activeConfigs.count() <= 0)
        return;

    QNetworkConfiguration cfg = activeConfigs.at(0);
    foreach(QNetworkConfiguration config, activeConfigs) {
        if (config.type() == QNetworkConfiguration::UserChoice) {
            cfg = config;
            break;
        }
    }

    session = new QNetworkSession(cfg);
    session->open();
    if (!session->waitForOpened(-1))
        return;
#endif

    QString dejavuPath(d->resourcePath % "/3rdparty/dejavu-fonts-ttf-2.32/ttf/");
    if (QDir(dejavuPath).exists()) {
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans.ttf");
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans-Bold.ttf");
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans-Oblique.ttf");
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans-BoldOblique.ttf");
        QApplication::setFont(QFont("DejaVu Sans"));
    }
}

Backend::~Backend()
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    session->close();
#endif

    delete d;
    d = 0;
}

void Backend::initialize()
{
    d->discoverEngines();
}

QString Backend::language() const
{
    //FIXME: derive from locale
    //Allow override
    return QString();
    //Bob is a testing translation placeholder
    //return QString("bob");
}

QList<QMHPlugin *> Backend::allEngines() const
{
    return d->allEngines;
}

QList<QObject *> Backend::advertizedEngines() const
{
    QList<QObject *> ret;
    foreach(QMHPlugin *engine, d->advertizedEngines) {
        ret << engine;
    }

    return ret;
}

QList<QObject *> Backend::skins() const
{
    return d->skins;
}

Backend* Backend::instance()
{
    if (!pSelf) {
        pSelf = new Backend();
    }
    return pSelf;
}

void Backend::destroy()
{
    delete pSelf;
    pSelf = 0;
}

QString Backend::basePath() const
{
    return d->basePath;
}

QString Backend::pluginPath() const
{
    return d->pluginPath;
}

QString Backend::resourcePath() const
{
    return d->resourcePath;
}

QString Backend::thumbnailPath() const
{
    return d->thumbnailPath;
}

bool Backend::transforms() const
{
#ifdef GL
    return (QGLFormat::hasOpenGL() && Config::isEnabled("transforms", true));
#else
    return false;
#endif
}

void Backend::advertizeEngine(QMHPlugin *engine)
{
    //Advertize to main menu
    QString role = engine->role();
    if (role.isEmpty())
        return;
    if (d->advertizedEngineRoles.contains(role)) {
        qWarning() << tr("Duplicate engine found for role %1").arg(role);
        return;
    } else {
        d->advertizedEngineRoles << role;
    }

    if (engine->advertized())
        d->advertizedEngines << engine;

    connect(engine, SIGNAL(pluginChanged()), this, SIGNAL(advertizedEnginesChanged()));
    emit advertizedEnginesChanged();
}

void Backend::openUrlExternally(const QUrl & url) const
{
    QDesktopServices::openUrl(url);
}

void Backend::log(const QString &logMsg)
{
    qDebug() << logMsg;
    d->log << logMsg << endl;
}

bool Backend::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::KeyPress
            || event->type() == QEvent::KeyRelease
            || event->type() == QEvent::MouseMove
            || event->type() == QEvent::MouseButtonPress)
    {
        d->inputIdleTimer.start();
    }

    return QObject::eventFilter(obj, event);
}

QObject *Backend::engineByRole(const QString &role)
{
    foreach (QObject *currentEngine, d->advertizedEngines)
        if (qobject_cast<QMHPlugin*>(currentEngine)->role() == role)
            return currentEngine;
    qWarning() << tr("Seeking a non-existant plugin, prepare to die");
    return 0;
}

QObject *Backend::engineByName(const QString &name)
{
    foreach (QObject *currentEngine, d->allEngines)
        if (qobject_cast<QMHPlugin*>(currentEngine)->name() == name)
            return currentEngine;

    return 0;
}

QObject *Backend::targetsModel() const
{
    if (!d->targetsModel) {
#ifdef QMH_AVAHI
        QAvahiServiceBrowserModel *model = new QAvahiServiceBrowserModel(const_cast<Backend *>(this));
        model->setAutoResolve(true);
        model->browse("_qmh._tcp", QAvahiServiceBrowserModel::HideIPv6 | QAvahiServiceBrowserModel::HideLocal);
        d->targetsModel = model;
#else
        d->targetsModel = new QStandardItemModel(const_cast<Backend *>(this));
#endif
    }
    return d->targetsModel;
}

#include "backend.moc"
<commit_msg>remove check for duplicate roles in plugins<commit_after>/****************************************************************************

This file is part of the QtMediaHub project on http://www.gitorious.org.

Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).*
All rights reserved.

Contact:  Nokia Corporation (qt-info@nokia.com)**

You may use this file under the terms of the BSD license as follows:

"Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."

****************************************************************************/

#include "backend.h"
#include "plugins/qmhplugin/qmhplugin.h"

#include "qmh-config.h"
#include "rpc/rpcconnection.h"
#include "skin.h"

#ifdef QMH_AVAHI
#include "qavahiservicebrowsermodel.h"
#endif

#include <QDir>
#include <QString>
#include <QPluginLoader>
#include <QCoreApplication>
#include <QVariant>
#include <QFileSystemModel>
#include <QDesktopServices>
#include <QFileSystemWatcher>

#ifdef GL
#include <QGLFormat>
#endif

#include <QDebug>

Backend* Backend::pSelf = 0;

class BackendPrivate : public QObject
{
    Q_OBJECT
public:
    BackendPrivate(Backend *p)
        : QObject(p),
      #ifdef Q_OS_MAC
          platformOffset("/../../.."),
      #endif
          basePath(QCoreApplication::applicationDirPath() + platformOffset),
          // Use "large" instead of appName to fit freedesktop spec
          thumbnailPath(Config::value("thumbnail-path", QDir::homePath() + "/.thumbnails/" + qApp->applicationName() + "/")),
          inputIdleTimer(this),
          backendTranslator(0),
          logFile(qApp->applicationName().append(".log")),
          targetsModel(0),
          pSelf(p)
    {
        // TODO: check install prefix
        skinPaths << "/usr/share/qtmediahub/skins/";
        skinPaths << QDir::homePath() + "/.qtmediahub/skins/";
        QDir skinPath(Config::value("skins", QString(basePath % "/skins")));
        if (skinPath.exists())
            skinPaths << skinPath.absolutePath();

        pluginPath = QDir(Config::value("plugins", QString(basePath % "/plugins"))).absolutePath();
        resourcePath = QDir(Config::value("resources", QString(basePath % "/resources"))).absolutePath();

        inputIdleTimer.setInterval(Config::value("idle-timeout", 120)*1000);
        inputIdleTimer.setSingleShot(true);
        inputIdleTimer.start();

        connect(&inputIdleTimer, SIGNAL(timeout()), pSelf, SIGNAL(inputIdle()));

        logFile.open(QIODevice::Text|QIODevice::ReadWrite);
        log.setDevice(&logFile);

        connect(&resourcePathMonitor,
                SIGNAL(directoryChanged(const QString &)),
                this,
                SLOT(handleDirChanged(const QString &)));

        foreach (QString skinPath, skinPaths)
            resourcePathMonitor.addPath(skinPath);
        resourcePathMonitor.addPath(pluginPath);

        QFileInfo thumbnailFolderInfo(thumbnailPath);
        if (!thumbnailFolderInfo.exists()) {
            QDir dir;
            dir.mkpath(thumbnailFolderInfo.absoluteFilePath());
        }

        discoverSkins();
    }

    ~BackendPrivate()
    {
        delete backendTranslator;
        backendTranslator = 0;
        qDeleteAll(pluginTranslators.begin(), pluginTranslators.end());
    }

public slots:
    void handleDirChanged(const QString &dir);

public:
    void resetLanguage();
    void discoverSkins();
    void discoverEngines();

    QSet<QString> advertizedEngineRoles;

    QList<QObject*> advertizedEngines;
    QList<QMHPlugin*> allEngines;

    const QString platformOffset;

    const QString basePath;
    QString pluginPath;
    QString resourcePath;
    const QString thumbnailPath;

    QStringList skinPaths;
    QList<QObject *> skins;

    QTimer inputIdleTimer;
    QTranslator *backendTranslator;
    QList<QTranslator*> pluginTranslators;
    QFile logFile;
    QTextStream log;
    QFileSystemWatcher resourcePathMonitor;

    QAbstractItemModel *targetsModel;

#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    QNetworkConfigurationManager mgr;
    QNetworkSession *session;
#endif

    Backend *pSelf;
};

void BackendPrivate::handleDirChanged(const QString &dir)
{
    if(dir == pluginPath) {
        qWarning() << "Changes in plugin path, probably about to eat your poodle";
        discoverEngines();
    } else if(skinPaths.contains(dir)) {
        qWarning() << "Changes in skin path, repopulating skins";
        discoverSkins();
    }
}

void BackendPrivate::resetLanguage()
{
    static QString baseTranslationPath(basePath % "/translations/");
    const QString language = Backend::instance()->language();
    delete backendTranslator;
    backendTranslator = new QTranslator(this);
    backendTranslator->load(baseTranslationPath % language % ".qm");
    qApp->installTranslator(backendTranslator);

    qDeleteAll(pluginTranslators.begin(), pluginTranslators.end());

    foreach(QMHPlugin *plugin, allEngines) {
        QTranslator *pluginTranslator = new QTranslator(this);
        pluginTranslator->load(baseTranslationPath % plugin->role() % "_" % language % ".qm");
        pluginTranslators << pluginTranslator;
        qApp->installTranslator(pluginTranslator);
    }
}

void BackendPrivate::discoverSkins()
{
    skins.clear();

    foreach (QString skinPath, skinPaths) {
        QStringList potentialSkins = QDir(skinPath).entryList(QDir::Dirs | QDir::NoDotAndDotDot);

        foreach(const QString &currentPath, potentialSkins) {
            if(QFile(skinPath % "/" % currentPath % "/" % currentPath).exists()) {
                Skin *skin = new Skin(currentPath, skinPath % "/" % currentPath % "/");
                skins << skin;
            }
        }
    }

    qWarning() << "Available skins:";
    foreach(QObject *skin, skins)
        qWarning() << "\t" << qobject_cast<Skin*>(skin)->name();
}

void BackendPrivate::discoverEngines()
{
    foreach(const QString fileName, QDir(pluginPath).entryList(QDir::Files)) {
        QString qualifiedFileName(pluginPath % "/" % fileName);
        QPluginLoader pluginLoader(qualifiedFileName);

        if (!pluginLoader.load()) {
            qWarning() << tr("Cant load plugin: %1 returns %2").arg(qualifiedFileName).arg(pluginLoader.errorString());
            continue;
        }

        QMHPlugin *plugin = qobject_cast<QMHPlugin*>(pluginLoader.instance());
        if (!plugin)
            qWarning() << tr("Invalid QMH plugin present: %1").arg(qualifiedFileName);
        else if (!plugin->dependenciesSatisfied())
            qWarning() << tr("Can't meet dependencies for %1").arg(qualifiedFileName);
        else if (plugin->role() == "undefined")
            qWarning() << tr("Plugin %1 has an undefined role").arg(qualifiedFileName);
        else {
            plugin->setParent(this);
            allEngines << plugin;
            Backend::instance()->advertizeEngine(plugin);
        }
    }
    resetLanguage();
}

Backend::Backend(QObject *parent)
    : QObject(parent),
      d(new BackendPrivate(this))
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    // Set Internet Access Point
    QList<QNetworkConfiguration> activeConfigs = d->mgr.allConfigurations();
    if (activeConfigs.count() <= 0)
        return;

    QNetworkConfiguration cfg = activeConfigs.at(0);
    foreach(QNetworkConfiguration config, activeConfigs) {
        if (config.type() == QNetworkConfiguration::UserChoice) {
            cfg = config;
            break;
        }
    }

    session = new QNetworkSession(cfg);
    session->open();
    if (!session->waitForOpened(-1))
        return;
#endif

    QString dejavuPath(d->resourcePath % "/3rdparty/dejavu-fonts-ttf-2.32/ttf/");
    if (QDir(dejavuPath).exists()) {
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans.ttf");
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans-Bold.ttf");
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans-Oblique.ttf");
        QFontDatabase::addApplicationFont(dejavuPath % "DejaVuSans-BoldOblique.ttf");
        QApplication::setFont(QFont("DejaVu Sans"));
    }
}

Backend::~Backend()
{
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO)
    session->close();
#endif

    delete d;
    d = 0;
}

void Backend::initialize()
{
    d->discoverEngines();
}

QString Backend::language() const
{
    //FIXME: derive from locale
    //Allow override
    return QString();
    //Bob is a testing translation placeholder
    //return QString("bob");
}

QList<QMHPlugin *> Backend::allEngines() const
{
    return d->allEngines;
}

QList<QObject *> Backend::advertizedEngines() const
{
    return d->advertizedEngines;
}

QList<QObject *> Backend::skins() const
{
    return d->skins;
}

Backend* Backend::instance()
{
    if (!pSelf) {
        pSelf = new Backend();
    }
    return pSelf;
}

void Backend::destroy()
{
    delete pSelf;
    pSelf = 0;
}

QString Backend::basePath() const
{
    return d->basePath;
}

QString Backend::pluginPath() const
{
    return d->pluginPath;
}

QString Backend::resourcePath() const
{
    return d->resourcePath;
}

QString Backend::thumbnailPath() const
{
    return d->thumbnailPath;
}

bool Backend::transforms() const
{
#ifdef GL
    return (QGLFormat::hasOpenGL() && Config::isEnabled("transforms", true));
#else
    return false;
#endif
}

void Backend::advertizeEngine(QMHPlugin *engine)
{
    //Advertize to main menu
    QString role = engine->role();
    if (role.isEmpty())
        return;

    if (engine->advertized())
        d->advertizedEngines << engine;

    connect(engine, SIGNAL(pluginChanged()), this, SIGNAL(advertizedEnginesChanged()));
    emit advertizedEnginesChanged();
}

void Backend::openUrlExternally(const QUrl & url) const
{
    QDesktopServices::openUrl(url);
}

void Backend::log(const QString &logMsg)
{
    qDebug() << logMsg;
    d->log << logMsg << endl;
}

bool Backend::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::KeyPress
            || event->type() == QEvent::KeyRelease
            || event->type() == QEvent::MouseMove
            || event->type() == QEvent::MouseButtonPress)
    {
        d->inputIdleTimer.start();
    }

    return QObject::eventFilter(obj, event);
}

QObject *Backend::engineByRole(const QString &role)
{
    foreach (QObject *currentEngine, d->advertizedEngines)
        if (qobject_cast<QMHPlugin*>(currentEngine)->role() == role)
            return currentEngine;
    qWarning() << tr("Seeking a non-existant plugin, prepare to die");
    return 0;
}

QObject *Backend::engineByName(const QString &name)
{
    foreach (QObject *currentEngine, d->allEngines)
        if (qobject_cast<QMHPlugin*>(currentEngine)->name() == name)
            return currentEngine;

    return 0;
}

QObject *Backend::targetsModel() const
{
    if (!d->targetsModel) {
#ifdef QMH_AVAHI
        QAvahiServiceBrowserModel *model = new QAvahiServiceBrowserModel(const_cast<Backend *>(this));
        model->setAutoResolve(true);
        model->browse("_qmh._tcp", QAvahiServiceBrowserModel::HideIPv6 | QAvahiServiceBrowserModel::HideLocal);
        d->targetsModel = model;
#else
        d->targetsModel = new QStandardItemModel(const_cast<Backend *>(this));
#endif
    }
    return d->targetsModel;
}

#include "backend.moc"
<|endoftext|>