PageRenderTime 62ms CodeModel.GetById 19ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/src/ois/src/win32/extras/WiiMote/OISWiiMoteFactoryCreator.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 206 lines | 131 code | 30 blank | 45 comment | 34 complexity | df5d040bfa60f15cdb5d82026888a553 MD5 | raw file
  1#include "OISConfig.h"
  2#ifdef OIS_WIN32_WIIMOTE_SUPPORT
  3/*
  4The zlib/libpng License
  5
  6Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
  7
  8This software is provided 'as-is', without any express or implied warranty. In no event will
  9the authors be held liable for any damages arising from the use of this software.
 10
 11Permission is granted to anyone to use this software for any purpose, including commercial 
 12applications, and to alter it and redistribute it freely, subject to the following
 13restrictions:
 14
 15    1. The origin of this software must not be misrepresented; you must not claim that 
 16		you wrote the original software. If you use this software in a product, 
 17		an acknowledgment in the product documentation would be appreciated but is 
 18		not required.
 19
 20    2. Altered source versions must be plainly marked as such, and must not be 
 21		misrepresented as being the original software.
 22
 23    3. This notice may not be removed or altered from any source distribution.
 24*/
 25#include "OISWiiMoteFactoryCreator.h"
 26#include "OISException.h"
 27#include "OISWiiMote.h"
 28#include <assert.h>
 29#include <boost/thread.hpp>   //include here, keep compilation times down
 30#include <boost/function.hpp>
 31#include <boost/bind.hpp>
 32
 33
 34using namespace OIS;
 35
 36//---------------------------------------------------------------------------------//
 37WiiMoteFactoryCreator::WiiMoteFactoryCreator() :
 38	mVendorName("cWiiMote"),
 39	mCount(0),
 40	mtThreadHandler(0),
 41	mtWiiMoteListMutex(0),
 42	mtThreadRunning(0)
 43{
 44	//Discover how many Wii's there are
 45	for( ; mCount < OIS_cWiiMote_MAX_WIIS; ++mCount )
 46	{
 47		cWiiMote wii;
 48		if( wii.ConnectToDevice(mCount) == false )
 49			break;
 50	}
 51
 52	//Store how many WiiMotes there were in the form of integer handles
 53	for(int i = 0; i < mCount; ++i)
 54		mFreeWiis.push_back(i);
 55
 56	//The mutex lasts the whole life of this class. The thread does not.
 57	mtWiiMoteListMutex = new boost::mutex();
 58}
 59
 60//---------------------------------------------------------------------------------//
 61WiiMoteFactoryCreator::~WiiMoteFactoryCreator()
 62{
 63	//Thread (once all objects destroyed) should be killed off already
 64	assert( (mtThreadRunning == false && mtThreadHandler == 0) && 
 65		"~WiiMoteFactoryCreator(): invalid state.. Some objects left dangling!");
 66
 67	delete mtWiiMoteListMutex;
 68}
 69
 70//---------------------------------------------------------------------------------//
 71DeviceList WiiMoteFactoryCreator::freeDeviceList()
 72{
 73	DeviceList list;
 74	for( std::deque<int>::iterator i = mFreeWiis.begin(); i != mFreeWiis.end(); ++i )
 75	{
 76		list.insert(std::make_pair(OISJoyStick, mVendorName));
 77	}
 78	return list;
 79}
 80
 81//---------------------------------------------------------------------------------//
 82int WiiMoteFactoryCreator::totalDevices(Type iType)
 83{
 84	if( iType == OISJoyStick )
 85		return mCount;
 86	else
 87		return 0;
 88}
 89
 90//---------------------------------------------------------------------------------//
 91int WiiMoteFactoryCreator::freeDevices(Type iType)
 92{
 93	if( iType == OISJoyStick )
 94		return (int)mFreeWiis.size();
 95	else
 96		return 0;
 97}
 98
 99//---------------------------------------------------------------------------------//
100bool WiiMoteFactoryCreator::vendorExist(Type iType, const std::string & vendor)
101{
102	if( iType == OISJoyStick && mVendorName == vendor )
103		return true;
104	else
105		return false;
106}
107
108//---------------------------------------------------------------------------------//
109Object* WiiMoteFactoryCreator::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
110{
111	if( mFreeWiis.size() > 0 && (vendor == "" || vendor == mVendorName ) )
112	{
113		int id = mFreeWiis.front();
114		mFreeWiis.pop_front();
115		WiiMote *wii = new WiiMote(creator, id, bufferMode, this);
116
117		if( mtThreadRunning == false )
118		{	//Create common thread manager (this is the first wiimote created)
119			mtThreadRunning = true;
120			mtThreadHandler = new boost::thread(boost::bind(&WiiMoteFactoryCreator::_updateWiiMotesThread, this));
121		}
122		
123		//Now, add new WiiMote to thread manager for polling
124		{	//Get an auto lock on the list of active wiimotes
125			boost::mutex::scoped_lock arrayLock(*mtWiiMoteListMutex);
126			mtInUseWiiMotes.push_back(wii);
127		}
128
129		return wii;
130	}
131	else
132		OIS_EXCEPT(E_InputDeviceNonExistant, "No Device found which matches description!");
133}
134
135//---------------------------------------------------------------------------------//
136void WiiMoteFactoryCreator::destroyObject(Object* obj)
137{
138	if( obj == 0 )
139		return;
140
141	int wiis_alive = 0;
142
143	{	//Get an auto lock on the list of active wiimotes
144		boost::mutex::scoped_lock arrayLock(*mtWiiMoteListMutex);
145
146		//Find object
147		std::vector<WiiMote*>::iterator i = std::find(mtInUseWiiMotes.begin(), mtInUseWiiMotes.end(), obj);
148		if( i == mtInUseWiiMotes.end() )
149			OIS_EXCEPT(E_General, "Device not found in wimote collection!");
150
151		//Erase opject
152		mtInUseWiiMotes.erase(i);
153
154		//Delete object
155		delete obj;
156
157		wiis_alive = (int)mtInUseWiiMotes.size();
158	}
159
160	//Destroy thread if no longer in use (we do this after unlocking mutex!)
161	if( wiis_alive == 0 && mtThreadRunning )
162	{
163		mtThreadRunning = false;
164		mtThreadHandler->join();
165		delete mtThreadHandler;
166		mtThreadHandler = 0;
167	}
168
169}
170
171//---------------------------------------------------------------------------------//
172void WiiMoteFactoryCreator::_returnWiiMote(int id)
173{	//Restore ID to controller pool
174	mFreeWiis.push_front(id);
175}
176
177//---------------------------------------------------------------------------------//
178bool WiiMoteFactoryCreator::_updateWiiMotesThread()
179{
180	boost::xtime timer;
181
182	while(mtThreadRunning)
183	{
184		int numMotes = 0;
185		{	//Get an auto lock on the list of active wiimotes
186			boost::mutex::scoped_lock arrayLock(*mtWiiMoteListMutex);
187			numMotes = (int)mtInUseWiiMotes.size();
188			for( std::vector<WiiMote*>::iterator i = mtInUseWiiMotes.begin(), e = mtInUseWiiMotes.end(); i != e; ++i )
189			{	//Update it
190				(*i)->_threadUpdate();
191			}
192		}
193
194		//ok, we have updated all wiimotes, let us rest a bit
195		//sleep time = 30 / 1000 
196		//boost::thread::sleep(xtime) todo xxx wip use sleep instead??
197		//boost::thread::yield();
198		boost::xtime_get(&timer, boost::TIME_UTC);
199		timer.nsec += 20000000; //20 000 000 ~= 1/50 sec
200		boost::thread::sleep(timer);
201	}
202
203	return true;
204}
205
206#endif