/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/src/sgx/core/threading/processthread.cpp

*/

#include "sgx/core/core.hpp"

CSGXProcessThread::CSGXProcessThread(const sgxCPU *pOnCPU) : CSGXThread(pOnCPU)
{
	m_ListAddMutex = CMutex::create();
	m_Telaps = m_NewTelaps = 1.0f/60.0f;

	CSGXThreadManager::get()->create(this);
}

CSGXProcessThread::~CSGXProcessThread() 
{
	m_ListAddMutex->destroy();
}

tMEM_SIZE CSGXProcessThread::start()
{
	tBOOL bThreadRunning = TRUE;
	while(bThreadRunning) {
		if (m_State == SGX_THREAD_STATE_RUNNING) {

			// process each object
			sgxVector<sgxObject *>::iterator it;
			for(it = m_List.begin();it!=m_List.end();++it) {
			  (*it)->update(m_Telaps);
			}

			// Merge the add list to the update list
			SGX_MUTEX_CAPTURE(m_ListAddMutex);
			for(it = m_AddList.begin();it!=m_AddList.end();++it) {
				m_List.push_back(*it);
			}
			m_AddList.clear();

			m_Telaps = m_NewTelaps;
			SGX_MUTEX_RELEASE(m_ListAddMutex);
		}

	   sgxYield();
	}

	return 0;
}

/**
This adds objects to the process list by first adding to a separate list
so that less time is spent locked in the list. This follows the idea that
merging two vectors takes less time than updating all the objects in the 
list.
*/
void CSGXProcessThread::addObject(sgxObject *pObj, tUINT32 iWeight) 
{
	SGX_MUTEX_CAPTURE(m_ListAddMutex);
	m_AddList.push_back(pObj);
	m_TotalWeight += iWeight;
	SGX_MUTEX_RELEASE(m_ListAddMutex);
}

/**
We re-use the list addmutex since it too must only be updated at
the end of the process
*/
void CSGXProcessThread::setTimeElapsed(tREAL32 t)
{
	SGX_MUTEX_CAPTURE(m_ListAddMutex);
	m_NewTelaps = t;
	SGX_MUTEX_RELEASE(m_ListAddMutex);
}


tUINT32 CSGXProcessThread::getNumprocesses() const
{
	return m_List.size() + m_AddList.size();
}

tUINT32 CSGXProcessThread::getNumprocessesWeighted() const
{
	return m_TotalWeight;
}

