<commit_before>/*************************************************************************
 *
 * Copyright 2016 Realm Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **************************************************************************/

#ifndef REALM_UTIL_ASSERT_HPP
#define REALM_UTIL_ASSERT_HPP

#include <realm/util/features.h>
#include <realm/util/terminate.hpp>

#if REALM_ENABLE_ASSERTIONS || defined(REALM_DEBUG)
#define REALM_ASSERTIONS_ENABLED 1
#else
#define REALM_ASSERTIONS_ENABLED 0
#endif

#define REALM_ASSERT_RELEASE(condition)                                                                              \
    (REALM_LIKELY(condition) ? static_cast<void>(0)                                                                  \
                             : realm::util::terminate("Assertion failed: " #condition, __FILE__, __LINE__))

#if REALM_ASSERTIONS_ENABLED
#define REALM_ASSERT(condition) REALM_ASSERT_RELEASE(condition)
#else
#define REALM_ASSERT(condition) static_cast<void>(sizeof bool(condition))
#endif

#ifdef REALM_DEBUG
#define REALM_ASSERT_DEBUG(condition) REALM_ASSERT_RELEASE(condition)
#else
#define REALM_ASSERT_DEBUG(condition) static_cast<void>(sizeof bool(condition))
#endif

#define REALM_STRINGIFY(X) #X

#define REALM_ASSERT_RELEASE_EX(condition, ...)                                                                      \
    (REALM_LIKELY(condition) ? static_cast<void>(0)                                                                  \
                             : realm::util::terminate_with_info("Assertion failed: " #condition, __LINE__, __FILE__, \
                                                                REALM_STRINGIFY((__VA_ARGS__)), __VA_ARGS__))

#ifdef REALM_DEBUG
#define REALM_ASSERT_DEBUG_EX REALM_ASSERT_RELEASE_EX
#else
#define REALM_ASSERT_DEBUG_EX(condition, ...) static_cast<void>(sizeof bool(condition))
#endif

// Becase the assert is used in noexcept methods, it's a bad idea to allocate
// buffer space for the message so therefore we must pass it to terminate which
// will 'cerr' it for us without needing any buffer
#if REALM_ENABLE_ASSERTIONS || defined(REALM_DEBUG)

#define REALM_ASSERT_EX REALM_ASSERT_RELEASE_EX

#define REALM_ASSERT_3(left, cmp, right)                                                                             \
    (REALM_LIKELY((left)cmp(right)) ? static_cast<void>(0)                                                           \
                                    : realm::util::terminate("Assertion failed: "                                    \
                                                             "" #left " " #cmp " " #right,                           \
                                                             __FILE__, __LINE__, left, right))

#define REALM_ASSERT_7(left1, cmp1, right1, logical, left2, cmp2, right2)                                            \
    (REALM_LIKELY(((left1)cmp1(right1))logical((left2)cmp2(right2)))                                                 \
         ? static_cast<void>(0)                                                                                \
         : realm::util::terminate("Assertion failed: "                                                               \
                                  "" #left1 " " #cmp1 " " #right1 " " #logical " "                                   \
                                  "" #left2 " " #cmp2 " " #right2,                                                   \
                                  __FILE__, __LINE__, left1, right1, left2, right2))

#define REALM_ASSERT_11(left1, cmp1, right1, logical1, left2, cmp2, right2, logical2, left3, cmp3, right3)           \
    (REALM_LIKELY(((left1)cmp1(right1))logical1((left2)cmp2(right2)) logical2((left3)cmp3(right3)))                  \
         ? static_cast<void>(0)                                                                                \
         : realm::util::terminate("Assertion failed: "                                                               \
                                  "" #left1 " " #cmp1 " " #right1 " " #logical1 " "                                  \
                                  "" #left2 " " #cmp2 " " #right2 " " #logical2 " "                                  \
                                  "" #left3 " " #cmp3 " " #right3,                                                   \
                                  __FILE__, __LINE__, left1, right1, left2, right2, left3, right3))
#else
#define REALM_ASSERT_EX(condition, ...) static_cast<void>(sizeof bool(condition))
#define REALM_ASSERT_3(left, cmp, right) static_cast<void>(sizeof bool((left)cmp(right)))
#define REALM_ASSERT_7(left1, cmp1, right1, logical, left2, cmp2, right2)                                            \
    static_cast<void>(sizeof bool(((left1)cmp1(right1))logical((left2)cmp2(right2))))
#define REALM_ASSERT_11(left1, cmp1, right1, logical1, left2, cmp2, right2, logical2, left3, cmp3, right3)           \
    static_cast<void>(sizeof bool(((left1)cmp1(right1))logical1((left2)cmp2(right2)) logical2((left3)cmp3(right3))))
#endif

#ifdef REALM_COVER
#define REALM_UNREACHABLE()
#define REALM_COVER_NEVER(x) false
#define REALM_COVER_ALWAYS(x) true
#else
#define REALM_UNREACHABLE() realm::util::terminate("Unreachable code", __FILE__, __LINE__)
#define REALM_COVER_NEVER(x) (x)
#define REALM_COVER_ALWAYS(x) (x)
#endif

#endif // REALM_UTIL_ASSERT_HPP
<commit_msg>Always call realm::util::terminate() from REALM_UNREACHABLE() to avoid noreturn warnings in coverage mode<commit_after>/*************************************************************************
 *
 * Copyright 2016 Realm Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **************************************************************************/

#ifndef REALM_UTIL_ASSERT_HPP
#define REALM_UTIL_ASSERT_HPP

#include <realm/util/features.h>
#include <realm/util/terminate.hpp>

#if REALM_ENABLE_ASSERTIONS || defined(REALM_DEBUG)
#define REALM_ASSERTIONS_ENABLED 1
#else
#define REALM_ASSERTIONS_ENABLED 0
#endif

#define REALM_ASSERT_RELEASE(condition)                                                                              \
    (REALM_LIKELY(condition) ? static_cast<void>(0)                                                                  \
                             : realm::util::terminate("Assertion failed: " #condition, __FILE__, __LINE__))

#if REALM_ASSERTIONS_ENABLED
#define REALM_ASSERT(condition) REALM_ASSERT_RELEASE(condition)
#else
#define REALM_ASSERT(condition) static_cast<void>(sizeof bool(condition))
#endif

#ifdef REALM_DEBUG
#define REALM_ASSERT_DEBUG(condition) REALM_ASSERT_RELEASE(condition)
#else
#define REALM_ASSERT_DEBUG(condition) static_cast<void>(sizeof bool(condition))
#endif

#define REALM_STRINGIFY(X) #X

#define REALM_ASSERT_RELEASE_EX(condition, ...)                                                                      \
    (REALM_LIKELY(condition) ? static_cast<void>(0)                                                                  \
                             : realm::util::terminate_with_info("Assertion failed: " #condition, __LINE__, __FILE__, \
                                                                REALM_STRINGIFY((__VA_ARGS__)), __VA_ARGS__))

#ifdef REALM_DEBUG
#define REALM_ASSERT_DEBUG_EX REALM_ASSERT_RELEASE_EX
#else
#define REALM_ASSERT_DEBUG_EX(condition, ...) static_cast<void>(sizeof bool(condition))
#endif

// Becase the assert is used in noexcept methods, it's a bad idea to allocate
// buffer space for the message so therefore we must pass it to terminate which
// will 'cerr' it for us without needing any buffer
#if REALM_ENABLE_ASSERTIONS || defined(REALM_DEBUG)

#define REALM_ASSERT_EX REALM_ASSERT_RELEASE_EX

#define REALM_ASSERT_3(left, cmp, right)                                                                             \
    (REALM_LIKELY((left)cmp(right)) ? static_cast<void>(0)                                                           \
                                    : realm::util::terminate("Assertion failed: "                                    \
                                                             "" #left " " #cmp " " #right,                           \
                                                             __FILE__, __LINE__, left, right))

#define REALM_ASSERT_7(left1, cmp1, right1, logical, left2, cmp2, right2)                                            \
    (REALM_LIKELY(((left1)cmp1(right1))logical((left2)cmp2(right2)))                                                 \
         ? static_cast<void>(0)                                                                                \
         : realm::util::terminate("Assertion failed: "                                                               \
                                  "" #left1 " " #cmp1 " " #right1 " " #logical " "                                   \
                                  "" #left2 " " #cmp2 " " #right2,                                                   \
                                  __FILE__, __LINE__, left1, right1, left2, right2))

#define REALM_ASSERT_11(left1, cmp1, right1, logical1, left2, cmp2, right2, logical2, left3, cmp3, right3)           \
    (REALM_LIKELY(((left1)cmp1(right1))logical1((left2)cmp2(right2)) logical2((left3)cmp3(right3)))                  \
         ? static_cast<void>(0)                                                                                \
         : realm::util::terminate("Assertion failed: "                                                               \
                                  "" #left1 " " #cmp1 " " #right1 " " #logical1 " "                                  \
                                  "" #left2 " " #cmp2 " " #right2 " " #logical2 " "                                  \
                                  "" #left3 " " #cmp3 " " #right3,                                                   \
                                  __FILE__, __LINE__, left1, right1, left2, right2, left3, right3))
#else
#define REALM_ASSERT_EX(condition, ...) static_cast<void>(sizeof bool(condition))
#define REALM_ASSERT_3(left, cmp, right) static_cast<void>(sizeof bool((left)cmp(right)))
#define REALM_ASSERT_7(left1, cmp1, right1, logical, left2, cmp2, right2)                                            \
    static_cast<void>(sizeof bool(((left1)cmp1(right1))logical((left2)cmp2(right2))))
#define REALM_ASSERT_11(left1, cmp1, right1, logical1, left2, cmp2, right2, logical2, left3, cmp3, right3)           \
    static_cast<void>(sizeof bool(((left1)cmp1(right1))logical1((left2)cmp2(right2)) logical2((left3)cmp3(right3))))
#endif

#define REALM_UNREACHABLE() realm::util::terminate("Unreachable code", __FILE__, __LINE__)
#ifdef REALM_COVER
#define REALM_COVER_NEVER(x) false
#define REALM_COVER_ALWAYS(x) true
#else
#define REALM_COVER_NEVER(x) (x)
#define REALM_COVER_ALWAYS(x) (x)
#endif

#endif // REALM_UTIL_ASSERT_HPP
<|endoftext|>


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

This source file is part of the
   ___                 __    __ _ _    _
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/
      Tutorial Framework
      http://www.ogre3d.org/tikiwiki/
-----------------------------------------------------------------------------
*/
#include "stdafx.h"
#include "BaseApplication.h"

//-------------------------------------------------------------------------------------
BaseApplication::BaseApplication(void)
    : mRoot(0),
    mSceneMgr(0),
    mWindow(0),
    mResourcesCfg(Ogre::StringUtil::BLANK),
    mPluginsCfg(Ogre::StringUtil::BLANK),
    mCursorWasVisible(false),
    mShutDown(false),
    mInputManager(0),
    mMouse(0),
    mKeyboard(0)
{
}

//-------------------------------------------------------------------------------------
BaseApplication::~BaseApplication(void)
{
	delete mController;
    //Remove ourself as a Window listener
    Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
    windowClosed(mWindow);
    delete mRoot;
}

	HWND mWindowHandle ;
	HWND mExternalWindow = (HWND)(0x000707EC);

LRESULT CALLBACK _WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	//note can use with OIS but need to pass more than just the mouse down message
	DWORD dwPID;
	bool posted = false;
	DWORD hThread ;
	hThread = GetWindowThreadProcessId(mExternalWindow, &dwPID);
	if (dwPID != NULL && hThread!= NULL )
	{
		SendMessage(mExternalWindow, msg, wParam, lParam);
	}
	return DefWindowProc( hwnd, msg, wParam, lParam );
	return 0;
}

//-------------------------------------------------------------------------------------
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, "Riftop");
		mRoot->initialise(false);
		UINT classStyle = 0;

		HINSTANCE hInst = NULL;

		// Register the window class
		// NB allow 4 bytes of window data for D3D11RenderWindow pointer
		WNDCLASS wc = { classStyle, _WndProc, 0, 0, hInst,
			LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
			(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "rwnd" };

		RegisterClass(&wc);

		DWORD dwStyle =  WS_VISIBLE | WS_CLIPCHILDREN;

		// Create our main window
		// Pass pointer to self
		mWindowHandle = CreateWindowA("rwnd", "Riftop", dwStyle,
			0, 0, 1280, 800, NULL, 0, hInst, this);

		NameValuePairList misc;
		misc["externalWindowHandle"] = StringConverter::toString((int)mWindowHandle);
		//misc["fullScreen"] = true;
		mWindow = mRoot->createRenderWindow("Main RenderWindow", 1280, 800, false, &misc);
		//Ogre::WindowEventUtilities::_addRenderWindow(mWindow);

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

    // 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");

    mRoot->addFrameListener(this);
}
//-------------------------------------------------------------------------------------
void BaseApplication::destroyScene(void)
{
}
//-------------------------------------------------------------------------------------
void BaseApplication::createViewports(void)
{

}
//-------------------------------------------------------------------------------------
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;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
}
//-------------------------------------------------------------------------------------
void BaseApplication::createResourceListener(void)
{

}
//-------------------------------------------------------------------------------------
void BaseApplication::loadResources(void)
{
	Ogre::ResourceGroupManager::getSingleton().createResourceGroup(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	if (Ogre::RTShader::ShaderGenerator::initialize())
	{
		// Grab the shader generator pointer.
		mShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();

		// Add the shader libs resource location.
		Ogre::ResourceGroupManager::getSingleton().addResourceLocation("D:\\Project\\Ogre\\OgreSource\\Samples\\Media\\RTShaderLib\\Cg", "FileSystem");

		// Set shader cache path.
		mShaderGenerator->setShaderCachePath("D:\\Project\\WolfGame\\WolfGame\\Debug\\shaders");
		//mShaderGenerator->
		// Set the scene manager.
		mShaderGenerator->addSceneManager(mSceneMgr);

		// Add a specialized sub-render (per-pixel lighting) state to the default scheme render state
		Ogre::RTShader::RenderState* pMainRenderState =
			mShaderGenerator->createOrRetrieveRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
		pMainRenderState->reset();

		//mShaderGenerator->addSubRenderStateFactory(new Ogre::RTShader::PerPixelLightingFactory);
		pMainRenderState->addTemplateSubRenderState(
			mShaderGenerator->createSubRenderState(Ogre::RTShader::FFPTexturing::Type));

		//return true;
	}

	mShaderGenerator->createShaderBasedTechnique("box/singlelight", Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

}
//-------------------------------------------------------------------------------------
void BaseApplication::go(void)
{
#ifdef _DEBUG
    mResourcesCfg = "D:\\Project\\WolfGame\\WolfGame\\Debug\\resources_d.cfg";
    mPluginsCfg = "D:\\Project\\WolfGame\\WolfGame\\Debug\\plugins_d.cfg";
#else
    mResourcesCfg = ".\\resources.cfg";
    mPluginsCfg = ".\\plugins.cfg";
#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();

	// 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();

	m_Windows = new SystemWindowManager( mSceneMgr, mShaderGenerator);
	m_Windows->RefreshWindowHandles();
	//window->DisplayWindow();

	mOculus = new OculusControl();
	mController = new CameraController::Controller(mWindow);
    mController->createCameras(mSceneMgr);

	if(mOculus->isInitialised())
	{
		mController->createViewports(mOculus->getDeviceInfo());
	}
	else
	{
		mController->createViewports();
	}

	mPlayer = new Player(mSceneMgr, mController->mBodyRotationNode);

	mScene = new WarehouseFloor(mSceneMgr);
	mWarehouseShown = true;
    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();
	//mBullet->StepPhysics(evt.timeSinceLastFrame);
	mController->mRotationNode->setOrientation(mOculus->getOrientation());
	mPlayer->processMovement(evt.timeSinceLastFrame);
    return true;
}
//-------------------------------------------------------------------------------------
bool BaseApplication::keyPressed( const OIS::KeyEvent &arg )
{
	/*if(arg.key == OIS::KC_1)
    {
		if(!mWarehouseShown )
		{
			mScene = new WarehouseFloor(mSceneMgr);
			mWarehouseShown = true;
		}
		else
		{
			delete mScene;
			mWarehouseShown = false;
		}
    }*/

	if(arg.key == OIS::KC_A)
    {
		mPlayer->addKeyboardInput(Ogre::Vector3(-1,0,0));
    }
	else if(arg.key == OIS::KC_D)
    {
        mPlayer->addKeyboardInput(Ogre::Vector3(1,0,0));
    }
	else if(arg.key == OIS::KC_S)
    {
        mPlayer->addKeyboardInput(Ogre::Vector3(0,0,1));
    }
	else if(arg.key == OIS::KC_W)
    {
        mPlayer->addKeyboardInput(Ogre::Vector3(0,0,-1));
    }
    else if(arg.key == OIS::KC_F5)   // refresh all textures
    {
        Ogre::TextureManager::getSingleton().reloadAll();
    }
	else if(arg.key == OIS::KC_SPACE)
    {
		m_Windows->ShowThumbnails();
        //mPlayer->jump();
    }
    else if (arg.key == OIS::KC_SYSRQ)   // take a screenshot
    {
        mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
    }
    else if (arg.key == OIS::KC_ESCAPE)
    {
        mShutDown = true;
    }
	else if(arg.key == OIS::KC_LCONTROL)
    {
        mPlayer->changeHeight(true);
    }
    return true;
}

bool BaseApplication::keyReleased( const OIS::KeyEvent &arg )
{
	if(arg.key == OIS::KC_A)
    {
		mPlayer->addKeyboardInput(Ogre::Vector3(1,0,0));
    }
	else if(arg.key == OIS::KC_D)
    {
        mPlayer->addKeyboardInput(Ogre::Vector3(-1,0,0));
    }
	else if(arg.key == OIS::KC_S)
    {
        mPlayer->addKeyboardInput(Ogre::Vector3(0,0,-1));
    }
	else if(arg.key == OIS::KC_W)
    {
        mPlayer->addKeyboardInput(Ogre::Vector3(0,0,1));
    }
	else if(arg.key == OIS::KC_LCONTROL)
    {
        mPlayer->changeHeight(false);
    }
	else if(arg.key == OIS::KC_SPACE)
    {
		m_Windows->RemoveThumbnails();
        //mPlayer->jump();
    }

    return true;
}

bool BaseApplication::mouseMoved( const OIS::MouseEvent &arg )
{
	mPlayer->mouseInput(Ogre::Vector2(arg.state.X.rel, arg.state.Y.rel));
    return true;
}

bool BaseApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	mPlayer->step();
    return true;
}

bool BaseApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID 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>a bit of cleanup for unused control<commit_after>/*
-----------------------------------------------------------------------------
Filename:    BaseApplication.cpp
-----------------------------------------------------------------------------

This source file is part of the
   ___                 __    __ _ _    _
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/
      Tutorial Framework
      http://www.ogre3d.org/tikiwiki/
-----------------------------------------------------------------------------
*/
#include "stdafx.h"
#include "BaseApplication.h"

//-------------------------------------------------------------------------------------
BaseApplication::BaseApplication(void)
    : mRoot(0),
    mSceneMgr(0),
    mWindow(0),
    mResourcesCfg(Ogre::StringUtil::BLANK),
    mPluginsCfg(Ogre::StringUtil::BLANK),
    mCursorWasVisible(false),
    mShutDown(false),
    mInputManager(0),
    mMouse(0),
    mKeyboard(0)
{
}

//-------------------------------------------------------------------------------------
BaseApplication::~BaseApplication(void)
{
	delete mController;
    //Remove ourself as a Window listener
    Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
    windowClosed(mWindow);
    delete mRoot;
}

	HWND mWindowHandle ;
	HWND mExternalWindow = (HWND)(0x000707EC);

LRESULT CALLBACK _WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	//note can use with OIS but need to pass more than just the mouse down message
	DWORD dwPID;
	bool posted = false;
	DWORD hThread ;
	hThread = GetWindowThreadProcessId(mExternalWindow, &dwPID);
	if (dwPID != NULL && hThread!= NULL )
	{
		SendMessage(mExternalWindow, msg, wParam, lParam);
	}
	return DefWindowProc( hwnd, msg, wParam, lParam );
	return 0;
}

//-------------------------------------------------------------------------------------
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, "Riftop");
		mRoot->initialise(false);
		UINT classStyle = 0;

		HINSTANCE hInst = NULL;

		// Register the window class
		// NB allow 4 bytes of window data for D3D11RenderWindow pointer
		WNDCLASS wc = { classStyle, _WndProc, 0, 0, hInst,
			LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
			(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "rwnd" };

		RegisterClass(&wc);

		DWORD dwStyle =  WS_VISIBLE | WS_CLIPCHILDREN;

		// Create our main window
		// Pass pointer to self
		mWindowHandle = CreateWindowA("rwnd", "Riftop", dwStyle,
			0, 0, 1280, 800, NULL, 0, hInst, this);

		NameValuePairList misc;
		misc["externalWindowHandle"] = StringConverter::toString((int)mWindowHandle);
		//misc["fullScreen"] = true;
		mWindow = mRoot->createRenderWindow("Main RenderWindow", 1280, 800, false, &misc);
		//Ogre::WindowEventUtilities::_addRenderWindow(mWindow);

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

    // 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");

    mRoot->addFrameListener(this);
}
//-------------------------------------------------------------------------------------
void BaseApplication::destroyScene(void)
{
}
//-------------------------------------------------------------------------------------
void BaseApplication::createViewports(void)
{

}
//-------------------------------------------------------------------------------------
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;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
}
//-------------------------------------------------------------------------------------
void BaseApplication::createResourceListener(void)
{

}
//-------------------------------------------------------------------------------------
void BaseApplication::loadResources(void)
{
	Ogre::ResourceGroupManager::getSingleton().createResourceGroup(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	if (Ogre::RTShader::ShaderGenerator::initialize())
	{
		// Grab the shader generator pointer.
		mShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();

		// Add the shader libs resource location.
		Ogre::ResourceGroupManager::getSingleton().addResourceLocation("D:\\Project\\Ogre\\OgreSource\\Samples\\Media\\RTShaderLib\\Cg", "FileSystem");

		// Set shader cache path.
		mShaderGenerator->setShaderCachePath("D:\\Project\\WolfGame\\WolfGame\\Debug\\shaders");
		//mShaderGenerator->
		// Set the scene manager.
		mShaderGenerator->addSceneManager(mSceneMgr);

		// Add a specialized sub-render (per-pixel lighting) state to the default scheme render state
		Ogre::RTShader::RenderState* pMainRenderState =
			mShaderGenerator->createOrRetrieveRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
		pMainRenderState->reset();

		//mShaderGenerator->addSubRenderStateFactory(new Ogre::RTShader::PerPixelLightingFactory);
		pMainRenderState->addTemplateSubRenderState(
			mShaderGenerator->createSubRenderState(Ogre::RTShader::FFPTexturing::Type));

		//return true;
	}

	mShaderGenerator->createShaderBasedTechnique("box/singlelight", Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

}
//-------------------------------------------------------------------------------------
void BaseApplication::go(void)
{
#ifdef _DEBUG
    mResourcesCfg = "D:\\Project\\WolfGame\\WolfGame\\Debug\\resources_d.cfg";
    mPluginsCfg = "D:\\Project\\WolfGame\\WolfGame\\Debug\\plugins_d.cfg";
#else
    mResourcesCfg = ".\\resources.cfg";
    mPluginsCfg = ".\\plugins.cfg";
#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();

	// 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();

	m_Windows = new SystemWindowManager( mSceneMgr, mShaderGenerator);
	m_Windows->RefreshWindowHandles();
	//window->DisplayWindow();

	mOculus = new OculusControl();
	mController = new CameraController::Controller(mWindow);
    mController->createCameras(mSceneMgr);

	if(mOculus->isInitialised())
	{
		mController->createViewports(mOculus->getDeviceInfo());
	}
	else
	{
		mController->createViewports();
	}

	mPlayer = new Player(mSceneMgr, mController->mBodyRotationNode);

	mScene = new WarehouseFloor(mSceneMgr);
	mWarehouseShown = true;
    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();
	mController->mRotationNode->setOrientation(mOculus->getOrientation());
	mPlayer->processMovement(evt.timeSinceLastFrame);
    return true;
}
//-------------------------------------------------------------------------------------
bool BaseApplication::keyPressed( const OIS::KeyEvent &arg )
{
	if(arg.key == OIS::KC_SPACE)
    {
		m_Windows->ShowThumbnails();
    }
    return true;
}

bool BaseApplication::keyReleased( const OIS::KeyEvent &arg )
{
	if(arg.key == OIS::KC_SPACE)
    {
		m_Windows->RemoveThumbnails();
    }

    return true;
}

bool BaseApplication::mouseMoved( const OIS::MouseEvent &arg )
{
	mPlayer->mouseInput(Ogre::Vector2(arg.state.X.rel, arg.state.Y.rel));
    return true;
}

bool BaseApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	mPlayer->step();
    return true;
}

bool BaseApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID 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>/******************************************************************************
 * This file is part of the Mula project
 * Copyright (c) 2011 Laszlo Papp <lpapp@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "dictionarymanager.h"

#include "pluginmanager.h"

#include <QtCore/QFileInfoList>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QPluginLoader>

using namespace MulaCore;

MULA_DEFINE_SINGLETON( DictionaryManager )

class DictionaryManager::Private
{
    public:
        Private()
        {
        }

        ~Private()
        {
        }

        QMultiHash<QString, QString> loadedDictionaryList;
};

DictionaryManager::DictionaryManager(QObject *parent)
    : MulaCore::Singleton< MulaCore::DictionaryManager >( parent )
    , d(new Private)
{
    loadDictionarySettings();
}

DictionaryManager::~DictionaryManager()
{
    saveDictionarySettings();
}

bool
DictionaryManager::isTranslatable(const QString &word)
{
    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(i.key());
        if (!dictionaryPlugin)
            continue;

        if (dictionaryPlugin->isTranslatable(i.value(), word))
            return true;
    }

    return false;
}

QString
DictionaryManager::translate(const QString &word)
{
    QString simplifiedWord = word.simplified();
    QString translatedWord;

    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(i.key());
        if (!dictionaryPlugin)
            continue;

        if (!dictionaryPlugin->isTranslatable(i.key(), simplifiedWord))
            continue;

        MulaCore::Translation translation = dictionaryPlugin->translate(i.key(), simplifiedWord);
        translatedWord.append(QString("
\n")
            + "" + translation.dictionaryName() + "
\n"
            + "" + translation.title() + "
\n"
            + translation.translation() + "
\n");
    }

    return translatedWord;
}

QStringList
DictionaryManager::findSimilarWords(const QString &word)
{
    QString simplifiedWord = word.simplified();
    QStringList similarWords;

    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(i.key());
        if (!dictionaryPlugin)
            continue;

        if (!dictionaryPlugin->features().testFlag(DictionaryPlugin::SearchSimilar))
            continue;

        QStringList similarWords = dictionaryPlugin->findSimilarWords(i.value(), simplifiedWord);
        foreach (const QString& similarWord, similarWords)
        {
            if (!similarWords.contains(similarWord, Qt::CaseSensitive))
                similarWords.append(similarWord);
        }
    }

    return similarWords;
}

QMultiHash<QString, QString>
DictionaryManager::availableDictionaryList() const
{
    QMultiHash<QString, QString> availableDictionaryList;

    // for (QHash<QString, QPluginLoader*>::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
    // {
        // DictionaryPlugin *plugin = qobject_cast<DictionaryPlugin*>((*i)->instance());
        // QStringList dictionaries = plugin->availableDictionaryList();
        // foreach (const QString& dictionary, dictionaries)
            // availableDictionaryList.append(DictionaryDataItem(i.key(), dictionary));
    // }

    return availableDictionaryList;
}

void
DictionaryManager::setLoadedDictionaryList(const QMultiHash<QString, QString> &loadedDictionaryList)
{
    QMultiHash<QString, QString> dictionaries = loadedDictionaryList;

    foreach (const QString& pluginName, dictionaries.keys())
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(pluginName);
        if (!dictionaryPlugin)
            continue;

        dictionaryPlugin->setLoadedDictionaryList(dictionaries.values());
        foreach (const QString& dictionaryName, dictionaryPlugin->loadedDictionaryList())
                dictionaries.insert(pluginName, dictionaryName);
    }

    d->loadedDictionaryList.clear();
    for (QMultiHash<QString, QString>::const_iterator i = loadedDictionaryList.begin(); i != loadedDictionaryList.end(); ++i)
    {
        if (dictionaries.keys().contains(i.key()) && dictionaries.value(i.key()).contains(i.value()))
            d->loadedDictionaryList.insert(i.key(), i.value());
    }
}

void
DictionaryManager::saveDictionarySettings()
{
    QStringList rawDictionaryList;

    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        rawDictionaryList.append(i.key());
        rawDictionaryList.append(i.value());
    }

    QSettings settings;
    settings.setValue("DictionaryManager/loadedDictionaryList", rawDictionaryList);
}

void
DictionaryManager::loadDictionarySettings()
{
    QSettings settings;
    QStringList rawDictionaryList = settings.value("DictionaryManager/loadedDictionaryList").toStringList();

    if (rawDictionaryList.isEmpty())
    {
        setLoadedDictionaryList(availableDictionaryList());
    }
    else
    {
        QMultiHash<QString, QString> dictionaries;
        for (QStringList::const_iterator i = rawDictionaryList.begin(); i != rawDictionaryList.end(); i += 2)
            dictionaries.insert(*i, *(i + 1));

        setLoadedDictionaryList(dictionaries);
    }
}

void
DictionaryManager::reloadDictionaryList()
{
    QMultiHash<QString, QString> loadedDictionaryList;
    // for (QHash<QString, QPluginLoader*>::const_iterator i = d->plugins.begin(); i != d->plugins.end(); ++i)
    // {
        // DictionaryPlugin *plugin = qobject_cast<DictionaryPlugin*>((*i)->instance());
        // plugin->setLoadedDictionaryList(plugin->loadedDictionaryList());

        // foreach(const QString& dictionaryName, plugin->loadedDictionaryList())
            // loadedDictionaryList.append(DictionaryDataItem(i.key(), dictionaryName));
    // }

    QMultiHash<QString, QString> oldDictionaryList = d->loadedDictionaryList;
    d->loadedDictionaryList.clear();

    for (QMultiHash<QString, QString>::const_iterator i = oldDictionaryList.begin(); i != oldDictionaryList.end(); ++i)
    {
        if (loadedDictionaryList.contains(i.key(), i.value()))
            d->loadedDictionaryList.insert(i.key(), i.value());
    }
}

#include "dictionarymanager.moc"
<commit_msg>Reimplement the internals of the availableDictionaryList "getter".<commit_after>/******************************************************************************
 * This file is part of the Mula project
 * Copyright (c) 2011 Laszlo Papp <lpapp@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "dictionarymanager.h"

#include "pluginmanager.h"

#include <QtCore/QFileInfoList>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QPluginLoader>

using namespace MulaCore;

MULA_DEFINE_SINGLETON( DictionaryManager )

class DictionaryManager::Private
{
    public:
        Private()
        {
        }

        ~Private()
        {
        }

        QMultiHash<QString, QString> loadedDictionaryList;
};

DictionaryManager::DictionaryManager(QObject *parent)
    : MulaCore::Singleton< MulaCore::DictionaryManager >( parent )
    , d(new Private)
{
    loadDictionarySettings();
}

DictionaryManager::~DictionaryManager()
{
    saveDictionarySettings();
}

bool
DictionaryManager::isTranslatable(const QString &word)
{
    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(i.key());
        if (!dictionaryPlugin)
            continue;

        if (dictionaryPlugin->isTranslatable(i.value(), word))
            return true;
    }

    return false;
}

QString
DictionaryManager::translate(const QString &word)
{
    QString simplifiedWord = word.simplified();
    QString translatedWord;

    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(i.key());
        if (!dictionaryPlugin)
            continue;

        if (!dictionaryPlugin->isTranslatable(i.key(), simplifiedWord))
            continue;

        MulaCore::Translation translation = dictionaryPlugin->translate(i.key(), simplifiedWord);
        translatedWord.append(QString("
\n")
            + "" + translation.dictionaryName() + "
\n"
            + "" + translation.title() + "
\n"
            + translation.translation() + "
\n");
    }

    return translatedWord;
}

QStringList
DictionaryManager::findSimilarWords(const QString &word)
{
    QString simplifiedWord = word.simplified();
    QStringList similarWords;

    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(i.key());
        if (!dictionaryPlugin)
            continue;

        if (!dictionaryPlugin->features().testFlag(DictionaryPlugin::SearchSimilar))
            continue;

        QStringList similarWords = dictionaryPlugin->findSimilarWords(i.value(), simplifiedWord);
        foreach (const QString& similarWord, similarWords)
        {
            if (!similarWords.contains(similarWord, Qt::CaseSensitive))
                similarWords.append(similarWord);
        }
    }

    return similarWords;
}

QMultiHash<QString, QString>
DictionaryManager::availableDictionaryList() const
{
    QMultiHash<QString, QString> availableDictionaryList;

    foreach (const QString& pluginName, MulaCore::PluginManager::instance()->availablePlugins())
    {
        DictionaryPlugin *dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(pluginName);
        QStringList dictionaries = dictionaryPlugin->availableDictionaryList();
        foreach (const QString& dictionary, dictionaries)
            availableDictionaryList.insert(pluginName, dictionary);
    }

    return availableDictionaryList;
}

void
DictionaryManager::setLoadedDictionaryList(const QMultiHash<QString, QString> &loadedDictionaryList)
{
    QMultiHash<QString, QString> dictionaries = loadedDictionaryList;

    foreach (const QString& pluginName, dictionaries.keys())
    {
        MulaCore::DictionaryPlugin* dictionaryPlugin = MulaCore::PluginManager::instance()->plugin(pluginName);
        if (!dictionaryPlugin)
            continue;

        dictionaryPlugin->setLoadedDictionaryList(dictionaries.values());
        foreach (const QString& dictionaryName, dictionaryPlugin->loadedDictionaryList())
                dictionaries.insert(pluginName, dictionaryName);
    }

    d->loadedDictionaryList.clear();
    for (QMultiHash<QString, QString>::const_iterator i = loadedDictionaryList.begin(); i != loadedDictionaryList.end(); ++i)
    {
        if (dictionaries.keys().contains(i.key()) && dictionaries.value(i.key()).contains(i.value()))
            d->loadedDictionaryList.insert(i.key(), i.value());
    }
}

void
DictionaryManager::saveDictionarySettings()
{
    QStringList rawDictionaryList;

    for (QMultiHash<QString, QString>::const_iterator i = d->loadedDictionaryList.begin(); i != d->loadedDictionaryList.end(); ++i)
    {
        rawDictionaryList.append(i.key());
        rawDictionaryList.append(i.value());
    }

    QSettings settings;
    settings.setValue("DictionaryManager/loadedDictionaryList", rawDictionaryList);
}

void
DictionaryManager::loadDictionarySettings()
{
    QSettings settings;
    QStringList rawDictionaryList = settings.value("DictionaryManager/loadedDictionaryList").toStringList();

    if (rawDictionaryList.isEmpty())
    {
        setLoadedDictionaryList(availableDictionaryList());
    }
    else
    {
        QMultiHash<QString, QString> dictionaries;
        for (QStringList::const_iterator i = rawDictionaryList.begin(); i != rawDictionaryList.end(); i += 2)
            dictionaries.insert(*i, *(i + 1));

        setLoadedDictionaryList(dictionaries);
    }
}

void
DictionaryManager::reloadDictionaryList()
{
    QMultiHash<QString, QString> loadedDictionaryList;
    // for (QHash<QString, QPluginLoader*>::const_iterator i = d->plugins.begin(); i != d->plugins.end(); ++i)
    // {
        // DictionaryPlugin *plugin = qobject_cast<DictionaryPlugin*>((*i)->instance());
        // plugin->setLoadedDictionaryList(plugin->loadedDictionaryList());

        // foreach(const QString& dictionaryName, plugin->loadedDictionaryList())
            // loadedDictionaryList.append(DictionaryDataItem(i.key(), dictionaryName));
    // }

    QMultiHash<QString, QString> oldDictionaryList = d->loadedDictionaryList;
    d->loadedDictionaryList.clear();

    for (QMultiHash<QString, QString>::const_iterator i = oldDictionaryList.begin(); i != oldDictionaryList.end(); ++i)
    {
        if (loadedDictionaryList.contains(i.key(), i.value()))
            d->loadedDictionaryList.insert(i.key(), i.value());
    }
}

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


<commit_before>#include "HTTPServer.hpp"
#include <czmq.h>
#include <iostream>
#include <sstream>
#include <cstring>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <assert.h>
#include "zutil.hpp"

#define controlEndpoint "inproc://http/control"

static size_t getFilesize(const char* filename) {
    struct stat st;
    stat(filename, &st);
    return st.st_size;
}

static bool fileExists(const char* file) {
    struct stat buf;
    return (stat(file, &buf) == 0);
}

/**
 * Represents a readonly static file instance which has been mmapped
 * into vmem and possible pre-cached by the kernel.
 */
class MMappedStaticFile {
public:
    /**
     * mmap a new static file.
     */
    MMappedStaticFile(const char* filename) {
        this->size = getFilesize(filename);
        fd = open(filename, O_RDONLY, 0);
        mem = mmap(nullptr, size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0);
        assert(mem != nullptr);
        //File will always be sent sequentially
        madvise(mem, size, MADV_SEQUENTIAL);
    }
    ~MMappedStaticFile() {
        assert(munmap(mem, size) == 0);
        close(fd);
    }
    //The mmapped memory
    void* mem;
    size_t size;
private:
    //The file descriptor that is mmapped
    int fd;
};

using namespace std;

YakHTTPServer::YakHTTPServer(zctx_t* ctxParam, const std::string& endpointParam, const std::string& staticFileRoot) : endpoint(endpointParam), ctx(ctxParam), thread(nullptr), logger(ctx, "HTTP Server"), staticFileRoot(staticFileRoot) {
    controlSocket = zsocket_new_bind(ctx, ZMQ_PAIR, controlEndpoint);
    //Start thread
    thread = new std::thread(std::mem_fun(&YakHTTPServer::workerMain), this);
}

//Static HTTP error msgs
static const char securityErrorMessage[] = "HTTP/1.1 403 Forbidden\r\nContent-type: text/plain\r\n\r\nSecurity error: Path must not contain ..";
static const char notFoundError[] = "HTTP/1.1 404 Not Found\r\nContent-type: text/plain\r\n\r\nFile not found";

/**
 * @return A constant string representing the MIME type, e.g. "text/plain")
 */
static const char* getMIMEType(const char* buffer) {
    //Find the beginning of the file ext === the last '.' occurrence -> strRchr
    const char* fileExtensionPtr = strrchr(buffer, '.');
    if(fileExtensionPtr == nullptr) {
        return "text/plain";
    }

    //We found an extension
    if(strcmp(".html", fileExtensionPtr) == 0) {
        return "text/html";
    } else if(strcmp(".js", fileExtensionPtr) == 0) {
        return "text/javascript";
    } else if(strcmp(".css", fileExtensionPtr) == 0) {
        return "text/css";
    } else if(strcmp(".jpg", fileExtensionPtr) == 0
        || strcmp(".jpeg", fileExtensionPtr) == 0) {
        return "image/jpeg";
    } else if(strcmp(".png", fileExtensionPtr) == 0) {
        return "image/png";
    } else if(strcmp(".ico", fileExtensionPtr) == 0) {
        return "image/x-icon";
    } else {
        return "text/plain";
    }
}

void YakHTTPServer::serveStaticFile(const char* fileURL) {
    sendReplyIdentity();
    //Security: Check if the file contains relative paths
    if(strstr(fileURL, "..") != nullptr) {
        if(zmq_send_const(httpSocket, securityErrorMessage, sizeof(securityErrorMessage), 0) == -1) {
            logger.warn("Sending security violation error to HTTP client failed: " + string(zmq_strerror(errno)));
        }
        return;
    }
    //No security violation, check if the file exists
    if(fileURL[0] == '/') {
        fileURL++;
    }
    if(fileURL[0] == '\0') {
        fileURL = "index.html";
    }
    string absoluteFilePath = staticFileRoot + string(fileURL);
    if(!fileExists(absoluteFilePath.c_str())) {
        if(zmq_send_const(httpSocket, notFoundError, sizeof(notFoundError), 0) == -1) {
            logger.warn("Sending HTTP 404 to client failed: " + string(zmq_strerror(errno)));
        }
        return;
    }
    //File exists, mmap if neccessary
    if(mappedFiles.count(absoluteFilePath) == 0) {
        logger.trace("mmap'ing static file " + absoluteFilePath);
        mappedFiles[absoluteFilePath] = new MMappedStaticFile(absoluteFilePath.c_str());
    }
    MMappedStaticFile* file = mappedFiles[absoluteFilePath];
    const char* mimeType = getMIMEType(fileURL);
    //Send the header
    string header("HTTP/1.1 200 OK\r\nContent-type: " + string(mimeType)
                    + "\r\nContent-Length: " + std::to_string(file->size) +  "\r\n\r\n");
    if(zmq_send_const(httpSocket, header.data(), header.size(), 0) == -1) {
        logger.warn("Sending HTTP header to client failed: " + string(zmq_strerror(errno)));
    }
    //Send data
    sendReplyIdentity();
    if(zmq_send_const(httpSocket, file->mem, file->size, 0) == -1) {
        logger.warn("Sending HTTP body to client failed: " + string(zmq_strerror(errno)));
    }
}

void YakHTTPServer::sendReplyIdentity() {
    if(unlikely(zmq_send_const (httpSocket, replyAddr, replyAddrSize, ZMQ_SNDMORE) == -1)) {
        logger.error("Error while sending stream reply adress: " + string(zmq_strerror(errno)));
    }
}

void YakHTTPServer::workerMain() {
    //TODO proper error handling
    logger.trace("HTTP Server starting on " + endpoint);
    //Initialize router socket
    httpSocket = zsocket_new(ctx, ZMQ_STREAM);
    assert(zsocket_bind(httpSocket, endpoint.c_str()) != -1);
    //Initialize other stuff
    zmq_msg_t replyAddrFrame;
    zmq_msg_init(&replyAddrFrame);
    zmq_msg_t request;
    zmq_msg_init(&request);
    zmq_msg_t response;
    zmq_msg_init(&response);
    //Initialize control socket (receives STOP cmd etc.)
    void* controlRecvSocket = zsocket_new_connect(ctx, ZMQ_PAIR, controlEndpoint);
    zmq_pollitem_t items[2];
    items[0].socket = httpSocket;
    items[0].events = ZMQ_POLLIN;
    items[1].socket = controlRecvSocket;
    items[1].events = ZMQ_POLLIN;
    while(true) {
         //  Get HTTP request
        assert(zmq_poll(items, 2, -1) != -1);
        //Check if we received a control msg
        if(items[1].revents) {
            //Valid control msgs: STOP, HUP
            char* controlMsg = zstr_recv(controlRecvSocket);
            if(strcmp(controlMsg, "HUP") == 0) {
                //HUP: munmap all static files --> 'reload' static files
                logger.trace("HUP received, reloading all mmap'ed files");
                for(auto pair : mappedFiles) {
                    delete pair.second;
                }
                free(controlMsg);
                continue;
            } else if(strcmp(controlMsg, "STOP") == 0) {
                free(controlMsg);
                break;
            } else {
                logger.warn("Received unknown control message: '" + string(controlMsg) + "'");
                continue;
            }
        }
        assert(items[0].revents);
        //Receive the reply adress
        zmq_msg_init(&replyAddrFrame);
        if(unlikely(zmq_msg_recv(&replyAddrFrame, httpSocket, 0) == -1)) {
            logger.error("HTTP critical error: Reply address could not be received correctly: " + string(zmq_strerror(errno)));
            continue;
        }
        //Receive the request itself (might be multi-part but we're ATM not interested in all the header
        if(unlikely(zmq_msg_recv(&request, httpSocket, 0) == -1)) {
            logger.error("Error while receiving HTTP request: " + std::string(zmq_strerror(errno)));
            continue;
        }
        //Extract the request type from the request
        char* requestData = (char*)zmq_msg_data(&request);
        bool isGETRequest = (memcmp(requestData, "GET ", 4) == 0);
        assert(isGETRequest);
        //Ensure there are no frames left to receive!
        recvAndIgnore(httpSocket);
        //Make a NUL-delimited string from the request path
        char* requestPath = strchr(requestData, ' ') + 1;
        *(strchr(requestPath, ' ')) = '\0';
        /**
         * NOTE: Even if the reply adress is non-const data,
         * it is deallocated by the IO thread when the connection is closed
         * and certainly won't change, so we can treat it as constant
         * and therefore zero-copy data while the HTTP connection is open
         */
        replyAddr = (char*) zmq_msg_data(&replyAddrFrame);
        replyAddrSize = zmq_msg_size(&replyAddrFrame);
        //TODO Check routes
        serveStaticFile(requestPath);
        //Cleanup
        closeTCPConnection();
        zmq_msg_close(&replyAddrFrame);
    }
    logger.debug("HTTP Server terminating...");
    zsocket_destroy(ctx, controlRecvSocket);
    zsocket_destroy(ctx, httpSocket);
    httpSocket = nullptr;
}

void YakHTTPServer::closeTCPConnection() {
    sendReplyIdentity();
    sendEmptyFrameMessage(httpSocket);
}

void YakHTTPServer::terminate() {
    if(thread != nullptr) {
        //Send control msg
        zstr_send(controlSocket, "STOP");
        zsocket_destroy(ctx, controlSocket);
        //Wait until the thread exists
        thread->join();
        delete thread;
        thread = nullptr;
    }
    logger.terminate();
}

YakHTTPServer::~YakHTTPServer() {
    terminate();
    //munmap all mmapped files
    for(auto pair : mappedFiles) {
        delete pair.second;
    }
}<commit_msg>Improve HTTP server safety<commit_after>#include "HTTPServer.hpp"
#include <czmq.h>
#include <iostream>
#include <sstream>
#include <cstring>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <assert.h>
#include "zutil.hpp"

#define controlEndpoint "inproc://http/control"

static size_t getFilesize(const char* filename) {
    struct stat st;
    stat(filename, &st);
    return st.st_size;
}

static bool fileExists(const char* file) {
    struct stat buf;
    return (stat(file, &buf) == 0);
}

/**
 * Represents a readonly static file instance which has been mmapped
 * into vmem and possible pre-cached by the kernel.
 */
class MMappedStaticFile {
public:
    /**
     * mmap a new static file.
     */
    MMappedStaticFile(const char* filename) {
        this->size = getFilesize(filename);
        fd = open(filename, O_RDONLY, 0);
        mem = mmap(nullptr, size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0);
        assert(mem != nullptr);
        //File will always be sent sequentially
        madvise(mem, size, MADV_SEQUENTIAL);
    }
    ~MMappedStaticFile() {
        assert(munmap(mem, size) == 0);
        close(fd);
    }
    //The mmapped memory
    void* mem;
    size_t size;
private:
    //The file descriptor that is mmapped
    int fd;
};

using namespace std;

YakHTTPServer::YakHTTPServer(zctx_t* ctxParam, const std::string& endpointParam, const std::string& staticFileRoot) : endpoint(endpointParam), ctx(ctxParam), thread(nullptr), logger(ctx, "HTTP Server"), staticFileRoot(staticFileRoot) {
    controlSocket = zsocket_new_bind(ctx, ZMQ_PAIR, controlEndpoint);
    //Start thread
    thread = new std::thread(std::mem_fun(&YakHTTPServer::workerMain), this);
}

//Static HTTP error msgs
static const char securityErrorMessage[] = "HTTP/1.1 403 Forbidden\r\nContent-type: text/plain\r\n\r\nSecurity error: Path must not contain ..";
static const char notFoundError[] = "HTTP/1.1 404 Not Found\r\nContent-type: text/plain\r\n\r\nFile not found";

/**
 * @return A constant string representing the MIME type, e.g. "text/plain")
 */
static const char* getMIMEType(const char* buffer) {
    //Find the beginning of the file ext === the last '.' occurrence -> strRchr
    const char* fileExtensionPtr = strrchr(buffer, '.');
    if(fileExtensionPtr == nullptr) {
        return "text/plain";
    }

    //We found an extension
    if(strcmp(".html", fileExtensionPtr) == 0) {
        return "text/html";
    } else if(strcmp(".js", fileExtensionPtr) == 0) {
        return "text/javascript";
    } else if(strcmp(".css", fileExtensionPtr) == 0) {
        return "text/css";
    } else if(strcmp(".jpg", fileExtensionPtr) == 0
        || strcmp(".jpeg", fileExtensionPtr) == 0) {
        return "image/jpeg";
    } else if(strcmp(".png", fileExtensionPtr) == 0) {
        return "image/png";
    } else if(strcmp(".ico", fileExtensionPtr) == 0) {
        return "image/x-icon";
    } else {
        return "text/plain";
    }
}

void YakHTTPServer::serveStaticFile(const char* fileURL) {
    sendReplyIdentity();
    //Security: Check if the file contains relative paths
    if(strstr(fileURL, "..") != nullptr) {
        if(zmq_send_const(httpSocket, securityErrorMessage, sizeof(securityErrorMessage), 0) == -1) {
            logger.warn("Sending security violation error to HTTP client failed: " + string(zmq_strerror(errno)));
        }
        return;
    }
    //No security violation, check if the file exists
    if(fileURL[0] == '/') {
        fileURL++;
    }
    if(fileURL[0] == '\0') {
        fileURL = "index.html";
    }
    string absoluteFilePath = staticFileRoot + string(fileURL);
    if(!fileExists(absoluteFilePath.c_str())) {
        if(zmq_send_const(httpSocket, notFoundError, sizeof(notFoundError), 0) == -1) {
            logger.warn("Sending HTTP 404 to client failed: " + string(zmq_strerror(errno)));
        }
        return;
    }
    //File exists, mmap if neccessary
    if(mappedFiles.count(absoluteFilePath) == 0) {
        logger.trace("mmap'ing static file " + absoluteFilePath);
        mappedFiles[absoluteFilePath] = new MMappedStaticFile(absoluteFilePath.c_str());
    }
    MMappedStaticFile* file = mappedFiles[absoluteFilePath];
    const char* mimeType = getMIMEType(fileURL);
    //Send the header
    string header("HTTP/1.1 200 OK\r\nContent-type: " + string(mimeType)
                    + "\r\nContent-Length: " + std::to_string(file->size) +  "\r\n\r\n");
    if(zmq_send_const(httpSocket, header.data(), header.size(), 0) == -1) {
        logger.warn("Sending HTTP header to client failed: " + string(zmq_strerror(errno)));
    }
    //Send data
    sendReplyIdentity();
    if(zmq_send_const(httpSocket, file->mem, file->size, 0) == -1) {
        logger.warn("Sending HTTP body to client failed: " + string(zmq_strerror(errno)));
    }
}

void YakHTTPServer::sendReplyIdentity() {
    if(unlikely(zmq_send (httpSocket, replyAddr, replyAddrSize, ZMQ_SNDMORE) == -1)) {
        logger.error("Error while sending stream reply adress: " + string(zmq_strerror(errno)));
    }
}

void YakHTTPServer::workerMain() {
    //TODO proper error handling
    logger.trace("HTTP Server starting on " + endpoint);
    //Initialize router socket
    httpSocket = zsocket_new(ctx, ZMQ_STREAM);
    assert(zsocket_bind(httpSocket, endpoint.c_str()) != -1);
    //Initialize other stuff
    zmq_msg_t replyAddrFrame;
    zmq_msg_init(&replyAddrFrame);
    zmq_msg_t request;
    zmq_msg_init(&request);
    zmq_msg_t response;
    zmq_msg_init(&response);
    //Initialize control socket (receives STOP cmd etc.)
    void* controlRecvSocket = zsocket_new_connect(ctx, ZMQ_PAIR, controlEndpoint);
    zmq_pollitem_t items[2];
    items[0].socket = httpSocket;
    items[0].events = ZMQ_POLLIN;
    items[1].socket = controlRecvSocket;
    items[1].events = ZMQ_POLLIN;
    while(true) {
         //  Get HTTP request
        assert(zmq_poll(items, 2, -1) != -1);
        //Check if we received a control msg
        if(items[1].revents) {
            //Valid control msgs: STOP, HUP
            char* controlMsg = zstr_recv(controlRecvSocket);
            if(strcmp(controlMsg, "HUP") == 0) {
                //HUP: munmap all static files --> 'reload' static files
                logger.trace("HUP received, reloading all mmap'ed files");
                for(auto pair : mappedFiles) {
                    delete pair.second;
                }
                free(controlMsg);
                continue;
            } else if(strcmp(controlMsg, "STOP") == 0) {
                free(controlMsg);
                break;
            } else {
                logger.warn("Received unknown control message: '" + string(controlMsg) + "'");
                continue;
            }
        }
        assert(items[0].revents);
        //Receive the reply adress
        zmq_msg_init(&replyAddrFrame);
        if(unlikely(zmq_msg_recv(&replyAddrFrame, httpSocket, 0) == -1)) {
            logger.error("HTTP critical error: Reply address could not be received correctly: " + string(zmq_strerror(errno)));
            continue;
        }
        //Receive the request itself (might be multi-part but we're ATM not interested in all the header
        if(unlikely(zmq_msg_recv(&request, httpSocket, 0) == -1)) {
            logger.error("Error while receiving HTTP request: " + std::string(zmq_strerror(errno)));
            continue;
        }
        //Extract the request type from the request
        char* requestData = (char*)zmq_msg_data(&request);
        bool isGETRequest = (memcmp(requestData, "GET ", 4) == 0);
        assert(isGETRequest);
        //Ensure there are no frames left to receive!
        recvAndIgnore(httpSocket);
        //Make a NUL-delimited string from the request path
        char* requestPath = strchr(requestData, ' ') + 1;
        *(strchr(requestPath, ' ')) = '\0';
        /**
         * NOTE: Even if the reply adress is non-const data,
         * it is deallocated by the IO thread when the connection is closed
         * and certainly won't change, so we can treat it as constant
         * and therefore zero-copy data while the HTTP connection is open
         */
        replyAddr = (char*) zmq_msg_data(&replyAddrFrame);
        replyAddrSize = zmq_msg_size(&replyAddrFrame);
        //TODO Check routes
        serveStaticFile(requestPath);
        //Cleanup
        closeTCPConnection();
        zmq_msg_close(&replyAddrFrame);
    }
    logger.debug("HTTP Server terminating...");
    zsocket_destroy(ctx, controlRecvSocket);
    zsocket_destroy(ctx, httpSocket);
    httpSocket = nullptr;
}

void YakHTTPServer::closeTCPConnection() {
    sendReplyIdentity();
    sendEmptyFrameMessage(httpSocket);
}

void YakHTTPServer::terminate() {
    if(thread != nullptr) {
        //Send control msg
        zstr_send(controlSocket, "STOP");
        zsocket_destroy(ctx, controlSocket);
        //Wait until the thread exists
        thread->join();
        delete thread;
        thread = nullptr;
    }
    logger.terminate();
}

YakHTTPServer::~YakHTTPServer() {
    terminate();
    //munmap all mmapped files
    for(auto pair : mappedFiles) {
        delete pair.second;
    }
}<|endoftext|>


<commit_before>#include "Controller.h"

#include "boost/thread.hpp"
#include "boost/bind.hpp"
#include "boost/progress.hpp"

#include "comm/FalconCommLibFTDI.h"
#include "grip/FalconGripFourButton.h"
#include "firmware/FalconFirmwareNovintSDK.h"

#include "kinematic/stamper/InverseKinematic.h"
#include "kinematic/stamper/JacobianMatrix.h"

#include <iostream>

namespace controller
{

	Controller::Controller()
	{
		falconKinematic = new libnifalcon::FalconKinematicStamper(false);
		std::cout << "Falcon initialization" << std::endl;
		//Don't set a kinematics model, since we're handing that ourselves
		falconModel = new libnifalcon::FalconDeviceBoostThread();
		int8_t i;
		falconModel->setFalconComm<libnifalcon::FalconCommLibFTDI>();
		falconModel->setFalconFirmware<libnifalcon::FalconFirmwareNovintSDK>();
		falconModel->setFalconGrip<libnifalcon::FalconGripFourButton>();

		if(!falconModel->open(0))
		{
			std::cout << "Can't open!" << std::endl;
		}

		falconModel->getFalconFirmware()->setHomingMode(true);
		int8_t count;
		if(!falconModel->isFirmwareLoaded())
		{
			std::cout << "Loading firmware..." << std::endl;
			std::cout << falconModel->setFirmwareFile("test_firmware.bin") << std::endl;
			for(int i = 0; i < 10; ++i)
			{
				if(falconModel->loadFirmware(10)) break;
			}
		}
		std::cout << "Kinematics initialization" << std::endl;
		if(falconModel->isFirmwareLoaded())
		{
			falconKinematic->initialize();
			std::cout << "Initialization finished" << std::endl;
			//boost::thread thread(boost::bind( &libnifalcon::FalconDevice::runThreadLoop, falconModel));
			falconModel->startThread();
		}
	}

	Controller::~Controller()
	{
		delete toolbox;
		delete viewer;
		delete falconModel;
		delete falconView;
	}

	void Controller::display()
	{
		if (viewer)
			viewer->display();
	}

	void Controller::reshape(int w, int h)
	{
		if (viewer)
			viewer->reshape(w, h);
	}

	void Controller::mouseButton(int button, int state, int x, int y)
	{
		if (viewer)
			viewer->mouseButton(button, state, x, y);
	}

	void Controller::mouseMove(int x, int y)
	{
		if (viewer)
			viewer->mouseMove(x, y);
	}

	void Controller::keyboard(unsigned char key, int x, int y)
	{
		if (viewer)
			viewer->keyboard(key, x, y);
	}

	void Controller::idle()
	{

		if(!falconModel->getFalconFirmware()->isHomed())
		{
			falconModel->getFalconFirmware()->setLEDStatus(libnifalcon::FalconFirmware::RED_LED);
			return;
		}
		else
		{
			falconModel->getFalconFirmware()->setLEDStatus(libnifalcon::FalconFirmware::GREEN_LED);
		}
		int16_t* encoders = new int16_t[3];
		encoders = falconModel->getFalconFirmware()->getEncoderValues();
		angle1 = falconKinematic->getTheta(encoders[0]);
		angle2 = falconKinematic->getTheta(encoders[1]);
		angle3 = falconKinematic->getTheta(encoders[2]);

		if (toolbox)
			toolbox->sync();

		gmtl::Vec3f angle_vec(gmtl::Math::deg2Rad(angle1), gmtl::Math::deg2Rad(angle2), gmtl::Math::deg2Rad(angle3));
	gmtl::Point3f position = falconKinematic->getDirectKinematic()->calculate(angle_vec);

		falconView->getEffector()->setPosition(position);

		libnifalcon::StamperKinematicImpl::Angle angle = libnifalcon::StamperKinematicImpl::InverseKinematic::calculate(position);

		falconView->getArm(view::Falcon::ARM_1)->setAngle(angle.theta1[view::Falcon::ARM_1]);
		falconView->getArm(view::Falcon::ARM_2)->setAngle(angle.theta1[view::Falcon::ARM_2]);
		falconView->getArm(view::Falcon::ARM_3)->setAngle(angle.theta1[view::Falcon::ARM_3]);

		falconView->getParallel(view::Falcon::ARM_1)->update(angle.theta1[view::Falcon::ARM_1],
															 angle.theta2[view::Falcon::ARM_1],
															 angle.theta3[view::Falcon::ARM_1]);

		falconView->getParallel(view::Falcon::ARM_2)->update(angle.theta1[view::Falcon::ARM_2],
															 angle.theta2[view::Falcon::ARM_2],
															 angle.theta3[view::Falcon::ARM_2]);

		falconView->getParallel(view::Falcon::ARM_3)->update(angle.theta1[view::Falcon::ARM_3],
															 angle.theta2[view::Falcon::ARM_3],
															 angle.theta3[view::Falcon::ARM_3]);
//		delete[] encoders;
/*
		if(falconModel->isHomed())
		{
			gmtl::Vec3f forceVector(0,0,torque1);
			gmtl::Matrix44f rotation;
			rotation.set(rotationMatrix[0], rotationMatrix[1], rotationMatrix[2], rotationMatrix[3],
						 rotationMatrix[4], rotationMatrix[5], rotationMatrix[6], rotationMatrix[7],
						 rotationMatrix[8], rotationMatrix[9], rotationMatrix[10], rotationMatrix[11],
						 rotationMatrix[12], rotationMatrix[13], rotationMatrix[14], rotationMatrix[15]);
			forceVector = rotation*forceVector;

			gmtl::Vec3f angularVelocity = libnifalcon::StamperKinematicImpl::JacobianMatrix::calculate(angle, forceVector);

			falconView->force->update(position, forceVector, rotation);

			float new_torque1 = -angularVelocity[libnifalcon::StamperKinematicImpl::ARM_1];
			float new_torque2 = -angularVelocity[libnifalcon::StamperKinematicImpl::ARM_2];
			float new_torque3 = -angularVelocity[libnifalcon::StamperKinematicImpl::ARM_3];

			falconModel->setTorque(libnifalcon::StamperKinematicImpl::ARM_1, new_torque1);
			falconModel->setTorque(libnifalcon::StamperKinematicImpl::ARM_2, new_torque2);
			falconModel->setTorque(libnifalcon::StamperKinematicImpl::ARM_3, new_torque3);
		}
*/

	}

	void Controller::createViewer()
	{
		viewer = new view::Viewer();
		falconView = new view::Falcon();
		viewer->setRootModel(falconView->getModel());
	}

	void Controller::createToolbox(int windowId, void (*idle)(void))
	{
		angle1 = 0;
		angle2 = 0;
		angle3 = 0;
		torque1 = 0;
		torque2 = 0;
		torque3 = 0;

		view::Toolbox::Parameter parameter;
		parameter.angle1 = &angle1;
		parameter.angle2 = &angle2;
		parameter.angle3 = &angle3;
		parameter.torque1 = &torque1;
		parameter.torque2 = &torque2;
		parameter.torque3 = &torque3;
		parameter.rotationMatrix = rotationMatrix;
		toolbox = new view::Toolbox(windowId, idle, parameter);
	}

	void Controller::hapticLoop()
	{

		while(1)
		{

			falconModel->runIOLoop();
			/*
			angle1 = falconModel->getTheta(model::Falcon::ARM_1);
			angle2 = falconModel->getTheta(model::Falcon::ARM_2);
			angle3 = falconModel->getTheta(model::Falcon::ARM_3);

			gmtl::Point3f position = directKinematic->calculate(gmtl::Vec3f(gmtl::Math::deg2Rad(angle1), gmtl::Math::deg2Rad(angle2), gmtl::Math::deg2Rad(angle3)));

			model::falcon::Angle angle = model::InverseKinematic::calculate(position);

			gmtl::Vec3f center(0,0,120);

			gmtl::Vec3f vecSphere(position-center);
			float radius = 20;
			float norme = 0;
			if (length(vecSphere)<radius)
			{
				norme = ((radius-length(vecSphere))/3)+20;
				//norme = 50;

			}
			normalize(vecSphere);
			gmtl::Vec3f forceVector = vecSphere;

			gmtl::Vec3f angularVelocity = model::JacobianMatrix::calculate(angle, forceVector);

			float torque1 = -angularVelocity[model::Falcon::ARM_1]*norme;
			float torque2 = -angularVelocity[model::Falcon::ARM_2]*norme;
			float torque3 = -angularVelocity[model::Falcon::ARM_3]*norme;

			falconModel->setTorque(model::Falcon::ARM_1, torque1);
			falconModel->setTorque(model::Falcon::ARM_2, torque2);
			falconModel->setTorque(model::Falcon::ARM_3, torque3);

*/
		}

	}

}
<commit_msg>Changed controller to use binary firmware headers for firmware loading Fixed position coordinate scaling<commit_after>#include "Controller.h"

#include "boost/thread.hpp"
#include "boost/bind.hpp"
#include "boost/progress.hpp"

#include "falcon/comm/FalconCommLibFTDI.h"
#include "falcon/grip/FalconGripFourButton.h"
#include "falcon/firmware/FalconFirmwareNovintSDK.h"
#include "falcon/util/FalconFirmwareBinaryNvent.h"

#include "falcon/kinematic/stamper/InverseKinematic.h"
#include "falcon/kinematic/stamper/JacobianMatrix.h"

#include <iostream>

namespace controller
{

	Controller::Controller()
	{
		falconKinematic = new libnifalcon::FalconKinematicStamper(false);
		std::cout << "Falcon initialization" << std::endl;
		//Don't set a kinematics model, since we're handing that ourselves
		falconModel = new libnifalcon::FalconDeviceBoostThread();
		int8_t i;
		falconModel->setFalconComm<libnifalcon::FalconCommLibFTDI>();
		falconModel->setFalconFirmware<libnifalcon::FalconFirmwareNovintSDK>();
		falconModel->setFalconGrip<libnifalcon::FalconGripFourButton>();

		if(!falconModel->open(0))
		{
			std::cout << "Can't open!" << std::endl;
		}

		falconModel->getFalconFirmware()->setHomingMode(true);
		int8_t count;
		if(!falconModel->isFirmwareLoaded())
		{
			std::cout << "Loading firmware..." << std::endl;
			for(int i = 0; i < 10; ++i)
			{
				if(!falconModel->getFalconFirmware()->loadFirmware(true, NOVINT_FALCON_NVENT_FIRMWARE_SIZE, const_cast<uint8_t*>(NOVINT_FALCON_NVENT_FIRMWARE)))
				{
					std::cout << "Could not load firmware" << std::endl;
				}
				else
				{
					break;
				}
			}
		}
		std::cout << "Kinematics initialization" << std::endl;
		if(falconModel->isFirmwareLoaded())
		{
			falconKinematic->initialize();
			std::cout << "Initialization finished" << std::endl;
			//boost::thread thread(boost::bind( &libnifalcon::FalconDevice::runThreadLoop, falconModel));
			falconModel->startThread();
		}
	}

	Controller::~Controller()
	{
		delete toolbox;
		delete viewer;
		delete falconModel;
		delete falconView;
	}

	void Controller::display()
	{
		if (viewer)
			viewer->display();
	}

	void Controller::reshape(int w, int h)
	{
		if (viewer)
			viewer->reshape(w, h);
	}

	void Controller::mouseButton(int button, int state, int x, int y)
	{
		if (viewer)
			viewer->mouseButton(button, state, x, y);
	}

	void Controller::mouseMove(int x, int y)
	{
		if (viewer)
			viewer->mouseMove(x, y);
	}

	void Controller::keyboard(unsigned char key, int x, int y)
	{
		if (viewer)
			viewer->keyboard(key, x, y);
	}

	void Controller::idle()
	{

		if(!falconModel->getFalconFirmware()->isHomed())
		{
			falconModel->getFalconFirmware()->setLEDStatus(libnifalcon::FalconFirmware::RED_LED);
			return;
		}
		else
		{
			falconModel->getFalconFirmware()->setLEDStatus(libnifalcon::FalconFirmware::GREEN_LED);
		}
		int16_t* encoders = new int16_t[3];
		encoders = falconModel->getFalconFirmware()->getEncoderValues();
		angle1 = falconKinematic->getTheta(encoders[0]);
		angle2 = falconKinematic->getTheta(encoders[1]);
		angle3 = falconKinematic->getTheta(encoders[2]);

		if (toolbox)
			toolbox->sync();

		gmtl::Vec3f angle_vec(gmtl::Math::deg2Rad(angle1), gmtl::Math::deg2Rad(angle2), gmtl::Math::deg2Rad(angle3));
		gmtl::Point3f position = falconKinematic->getDirectKinematic()->calculate(angle_vec);
		gmtl::Point3f position_new = position;
		position_new *= 1000.0;
		falconView->getEffector()->setPosition(position_new);

		libnifalcon::StamperKinematicImpl::Angle angle = libnifalcon::StamperKinematicImpl::InverseKinematic::calculate(position);

		falconView->getArm(view::Falcon::ARM_1)->setAngle(angle.theta1[view::Falcon::ARM_1]);
		falconView->getArm(view::Falcon::ARM_2)->setAngle(angle.theta1[view::Falcon::ARM_2]);
		falconView->getArm(view::Falcon::ARM_3)->setAngle(angle.theta1[view::Falcon::ARM_3]);

		falconView->getParallel(view::Falcon::ARM_1)->update(angle.theta1[view::Falcon::ARM_1],
															 angle.theta2[view::Falcon::ARM_1],
															 angle.theta3[view::Falcon::ARM_1]);

		falconView->getParallel(view::Falcon::ARM_2)->update(angle.theta1[view::Falcon::ARM_2],
															 angle.theta2[view::Falcon::ARM_2],
															 angle.theta3[view::Falcon::ARM_2]);

		falconView->getParallel(view::Falcon::ARM_3)->update(angle.theta1[view::Falcon::ARM_3],
															 angle.theta2[view::Falcon::ARM_3],
															 angle.theta3[view::Falcon::ARM_3]);
//		delete[] encoders;
/*
		if(falconModel->isHomed())
		{
			gmtl::Vec3f forceVector(0,0,torque1);
			gmtl::Matrix44f rotation;
			rotation.set(rotationMatrix[0], rotationMatrix[1], rotationMatrix[2], rotationMatrix[3],
						 rotationMatrix[4], rotationMatrix[5], rotationMatrix[6], rotationMatrix[7],
						 rotationMatrix[8], rotationMatrix[9], rotationMatrix[10], rotationMatrix[11],
						 rotationMatrix[12], rotationMatrix[13], rotationMatrix[14], rotationMatrix[15]);
			forceVector = rotation*forceVector;

			gmtl::Vec3f angularVelocity = libnifalcon::StamperKinematicImpl::JacobianMatrix::calculate(angle, forceVector);

			falconView->force->update(position, forceVector, rotation);

			float new_torque1 = -angularVelocity[libnifalcon::StamperKinematicImpl::ARM_1];
			float new_torque2 = -angularVelocity[libnifalcon::StamperKinematicImpl::ARM_2];
			float new_torque3 = -angularVelocity[libnifalcon::StamperKinematicImpl::ARM_3];

			falconModel->setTorque(libnifalcon::StamperKinematicImpl::ARM_1, new_torque1);
			falconModel->setTorque(libnifalcon::StamperKinematicImpl::ARM_2, new_torque2);
			falconModel->setTorque(libnifalcon::StamperKinematicImpl::ARM_3, new_torque3);
		}
*/

	}

	void Controller::createViewer()
	{
		viewer = new view::Viewer();
		falconView = new view::Falcon();
		viewer->setRootModel(falconView->getModel());
	}

	void Controller::createToolbox(int windowId, void (*idle)(void))
	{
		angle1 = 0;
		angle2 = 0;
		angle3 = 0;
		torque1 = 0;
		torque2 = 0;
		torque3 = 0;

		view::Toolbox::Parameter parameter;
		parameter.angle1 = &angle1;
		parameter.angle2 = &angle2;
		parameter.angle3 = &angle3;
		parameter.torque1 = &torque1;
		parameter.torque2 = &torque2;
		parameter.torque3 = &torque3;
		parameter.rotationMatrix = rotationMatrix;
		toolbox = new view::Toolbox(windowId, idle, parameter);
	}

	void Controller::hapticLoop()
	{

		while(1)
		{

			falconModel->runIOLoop();
			/*
			angle1 = falconModel->getTheta(model::Falcon::ARM_1);
			angle2 = falconModel->getTheta(model::Falcon::ARM_2);
			angle3 = falconModel->getTheta(model::Falcon::ARM_3);

			gmtl::Point3f position = directKinematic->calculate(gmtl::Vec3f(gmtl::Math::deg2Rad(angle1), gmtl::Math::deg2Rad(angle2), gmtl::Math::deg2Rad(angle3)));

			model::falcon::Angle angle = model::InverseKinematic::calculate(position);

			gmtl::Vec3f center(0,0,120);

			gmtl::Vec3f vecSphere(position-center);
			float radius = 20;
			float norme = 0;
			if (length(vecSphere)<radius)
			{
				norme = ((radius-length(vecSphere))/3)+20;
				//norme = 50;

			}
			normalize(vecSphere);
			gmtl::Vec3f forceVector = vecSphere;

			gmtl::Vec3f angularVelocity = model::JacobianMatrix::calculate(angle, forceVector);

			float torque1 = -angularVelocity[model::Falcon::ARM_1]*norme;
			float torque2 = -angularVelocity[model::Falcon::ARM_2]*norme;
			float torque3 = -angularVelocity[model::Falcon::ARM_3]*norme;

			falconModel->setTorque(model::Falcon::ARM_1, torque1);
			falconModel->setTorque(model::Falcon::ARM_2, torque2);
			falconModel->setTorque(model::Falcon::ARM_3, torque3);

*/
		}

	}

}
<|endoftext|>