Erwin Coumans: Abstract the physics engine Charlie C: Joystick fixes Me: Moved the ray cast (shadows, mouse sensor & ray sensor)
		
			
				
	
	
		
			276 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * $Id$
 | 
						|
 *
 | 
						|
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License
 | 
						|
 * as published by the Free Software Foundation; either version 2
 | 
						|
 * of the License, or (at your option) any later version. The Blender
 | 
						|
 * Foundation also sells licenses for use in proprietary software under
 | 
						|
 * the Blender License.  See http://www.blender.org/BL/ for information
 | 
						|
 * about this.
 | 
						|
 *
 | 
						|
 * This program 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 General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software Foundation,
 | 
						|
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 | 
						|
 *
 | 
						|
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * The Original Code is: all of this file.
 | 
						|
 *
 | 
						|
 * Contributor(s): none yet.
 | 
						|
 *
 | 
						|
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 | 
						|
 * NetworkSceneManagement generic implementation
 | 
						|
 */
 | 
						|
#include <stdio.h>
 | 
						|
#include <MT_assert.h>
 | 
						|
#include <algorithm>
 | 
						|
 | 
						|
#include "NG_NetworkScene.h"
 | 
						|
#include "NG_NetworkDeviceInterface.h"
 | 
						|
#include "NG_NetworkMessage.h"
 | 
						|
#include "NG_NetworkObject.h"
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
NG_NetworkScene::NG_NetworkScene(NG_NetworkDeviceInterface* nic)
 | 
						|
{
 | 
						|
	m_networkdevice = nic;
 | 
						|
}
 | 
						|
 | 
						|
NG_NetworkScene::~NG_NetworkScene()
 | 
						|
{
 | 
						|
	ClearAllMessageMaps();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * progress one frame, handle all network traffic
 | 
						|
 */
 | 
						|
void NG_NetworkScene::proceed(double curtime)
 | 
						|
{
 | 
						|
	if (!m_networkdevice) return;
 | 
						|
	if (!m_networkdevice->IsOnline()) return;
 | 
						|
 | 
						|
	ClearAllMessageMaps();
 | 
						|
 | 
						|
	// read all NetworkMessages from the device
 | 
						|
	vector<NG_NetworkMessage*> messages =
 | 
						|
		m_networkdevice->RetrieveNetworkMessages();
 | 
						|
 | 
						|
	vector<NG_NetworkMessage*>::iterator mesit = messages.begin();
 | 
						|
	for (; !(mesit == messages.end()); mesit++) {
 | 
						|
		NG_NetworkMessage* message = (*mesit);
 | 
						|
		vector<NG_NetworkMessage*>* tmplist=NULL;
 | 
						|
 | 
						|
		vector<NG_NetworkMessage*>** tmplistptr =
 | 
						|
			m_messagesByDestinationName[message->GetDestinationName()];
 | 
						|
		// if there is already a vector of messages, append, else create
 | 
						|
		// a new vector and insert into map
 | 
						|
		if (!tmplistptr) {
 | 
						|
			tmplist = new vector<NG_NetworkMessage*>;
 | 
						|
			m_messagesByDestinationName.insert(message->GetDestinationName(),
 | 
						|
											   tmplist);
 | 
						|
		} else {
 | 
						|
			tmplist = *tmplistptr;
 | 
						|
		}
 | 
						|
		message->AddRef();
 | 
						|
		tmplist->push_back(message);
 | 
						|
		tmplist = NULL;
 | 
						|
 | 
						|
		tmplistptr = m_messagesBySenderName[message->GetSenderName()];
 | 
						|
		// if there is already a vector of messages, append, else create
 | 
						|
		// a new vector and insert into map
 | 
						|
		if (!tmplistptr) {
 | 
						|
			tmplist = new vector<NG_NetworkMessage*>;
 | 
						|
			m_messagesBySenderName.insert(message->GetSenderName(), tmplist);
 | 
						|
		}  else {
 | 
						|
			tmplist = *tmplistptr;
 | 
						|
		}
 | 
						|
		message->AddRef();
 | 
						|
		tmplist->push_back(message);
 | 
						|
		tmplist = NULL;
 | 
						|
		
 | 
						|
		tmplistptr = m_messagesBySubject[message->GetSubject()];
 | 
						|
		// if there is already a vector of messages, append, else create
 | 
						|
		// a new vector and insert into map
 | 
						|
		if (!tmplistptr) {
 | 
						|
			tmplist = new vector<NG_NetworkMessage*>;
 | 
						|
			m_messagesBySubject.insert(message->GetSubject(), tmplist);
 | 
						|
		}  else {
 | 
						|
			tmplist = *tmplistptr;
 | 
						|
		}
 | 
						|
		message->AddRef();
 | 
						|
		tmplist->push_back(message);
 | 
						|
		tmplist = NULL;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * add a network object to the network scene
 | 
						|
 */
 | 
						|
void NG_NetworkScene::AddObject(NG_NetworkObject* object)
 | 
						|
{
 | 
						|
	if (! m_networkdevice->IsOnline()) return;
 | 
						|
 | 
						|
	STR_String name = object->GetName();
 | 
						|
	m_networkObjects.insert(name, object);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * remove a network object from the network scene
 | 
						|
 */
 | 
						|
void NG_NetworkScene::RemoveObject(NG_NetworkObject* object)
 | 
						|
{
 | 
						|
	if (! m_networkdevice->IsOnline()) return;
 | 
						|
 | 
						|
	STR_String name = object->GetName();
 | 
						|
	m_networkObjects.remove(name);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * remove all network scene objects at once
 | 
						|
 */
 | 
						|
void NG_NetworkScene::RemoveAllObjects()
 | 
						|
{
 | 
						|
	m_networkObjects.clear();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * get a single network object given its name
 | 
						|
 */
 | 
						|
NG_NetworkObject* NG_NetworkScene::FindNetworkObject(const STR_String& objname) {
 | 
						|
	NG_NetworkObject *nwobj = NULL;
 | 
						|
	if (! m_networkdevice->IsOnline()) return nwobj;
 | 
						|
 | 
						|
	NG_NetworkObject **nwobjptr = m_networkObjects[objname];
 | 
						|
	if (nwobjptr) {
 | 
						|
		nwobj = *nwobjptr;
 | 
						|
	}
 | 
						|
 | 
						|
	return nwobj;
 | 
						|
}
 | 
						|
 | 
						|
bool NG_NetworkScene::ConstraintsAreValid(
 | 
						|
	const STR_String& from,
 | 
						|
	const STR_String& subject,
 | 
						|
	NG_NetworkMessage* message)
 | 
						|
{
 | 
						|
	vector<NG_NetworkMessage*>** fromlistptr =  m_messagesBySenderName[from];
 | 
						|
	vector<NG_NetworkMessage*>** subjectlistptr =  m_messagesBySubject[subject];
 | 
						|
 | 
						|
	vector<NG_NetworkMessage*>* fromlist = (fromlistptr ? *fromlistptr : NULL);
 | 
						|
	vector<NG_NetworkMessage*>* subjectlist = (subjectlistptr ? *subjectlistptr : NULL);
 | 
						|
	
 | 
						|
	return (
 | 
						|
		( from.IsEmpty()    || (!fromlist ? false    : (!(std::find(fromlist->begin(), fromlist->end(), message)       == fromlist->end())))
 | 
						|
		) &&
 | 
						|
		( subject.IsEmpty() || (!subjectlist ? false : (!(std::find(subjectlist->begin(), subjectlist->end(), message) == subjectlist->end())))
 | 
						|
		));
 | 
						|
}
 | 
						|
 | 
						|
vector<NG_NetworkMessage*> NG_NetworkScene::FindMessages(
 | 
						|
	const STR_String& to,
 | 
						|
	const STR_String& from,
 | 
						|
	const STR_String& subject,
 | 
						|
	bool spamallowed)
 | 
						|
{
 | 
						|
	vector<NG_NetworkMessage*> foundmessages;
 | 
						|
	bool notfound = false;
 | 
						|
 | 
						|
	// broad phase
 | 
						|
	notfound = ((to.IsEmpty() || spamallowed) ? notfound : m_messagesByDestinationName[to] == NULL);
 | 
						|
	if (!notfound)
 | 
						|
		notfound = (from.IsEmpty() ? notfound : m_messagesBySenderName[from] == NULL);
 | 
						|
	if (!notfound)
 | 
						|
		notfound = (subject.IsEmpty() ? notfound : m_messagesBySubject[subject] == NULL);
 | 
						|
	if (notfound) {
 | 
						|
		// it's definately NOT in the scene, so stop looking
 | 
						|
	} else { // narrow phase
 | 
						|
		// possibly it's there, but maybe not (false hit)
 | 
						|
		if (to.IsEmpty()) {
 | 
						|
			// take all messages, and check other fields
 | 
						|
			MT_assert(!"objectnames that are empty are not valid, so make it a hobby project :)\n");
 | 
						|
		} else {
 | 
						|
			//todo: find intersection of messages (that are in other 2 maps)
 | 
						|
			vector<NG_NetworkMessage*>** tolistptr = m_messagesByDestinationName[to];
 | 
						|
			if (tolistptr) {
 | 
						|
				vector<NG_NetworkMessage*>* tolist = *tolistptr;
 | 
						|
				vector<NG_NetworkMessage*>::iterator listit;
 | 
						|
				for (listit=tolist->begin();!(listit==tolist->end());listit++) {
 | 
						|
					NG_NetworkMessage* message = *listit;
 | 
						|
					if (ConstraintsAreValid(from, subject, message)) {
 | 
						|
						message->AddRef();
 | 
						|
						foundmessages.push_back(message);
 | 
						|
					}
 | 
						|
				} 
 | 
						|
			}
 | 
						|
			// TODO find intersection of messages (that are in other 2 maps)
 | 
						|
			if (spamallowed) {
 | 
						|
				tolistptr = m_messagesByDestinationName[""];
 | 
						|
				if (tolistptr) {
 | 
						|
					vector<NG_NetworkMessage*>* tolist = *tolistptr;
 | 
						|
					vector<NG_NetworkMessage*>::iterator listit;
 | 
						|
					for (listit=tolist->begin();!(listit==tolist->end());listit++) {
 | 
						|
						NG_NetworkMessage* message = *listit;
 | 
						|
						if (ConstraintsAreValid(from, subject, message)) {
 | 
						|
							message->AddRef();
 | 
						|
							foundmessages.push_back(message);
 | 
						|
						}
 | 
						|
					} 
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} 
 | 
						|
	return foundmessages;
 | 
						|
}
 | 
						|
 | 
						|
void NG_NetworkScene::SendMessage(
 | 
						|
	const STR_String& to,
 | 
						|
	const STR_String& from,
 | 
						|
	const STR_String& subject,
 | 
						|
	const STR_String& message)
 | 
						|
{
 | 
						|
	NG_NetworkMessage* msg = new NG_NetworkMessage(to, from, subject, message);
 | 
						|
	m_networkdevice->SendNetworkMessage(msg);
 | 
						|
	msg->Release();
 | 
						|
}
 | 
						|
 | 
						|
void NG_NetworkScene::ClearAllMessageMaps(void)
 | 
						|
{
 | 
						|
	ClearMessageMap(m_messagesByDestinationName);
 | 
						|
	ClearMessageMap(m_messagesBySenderName);
 | 
						|
	ClearMessageMap(m_messagesBySubject);
 | 
						|
}
 | 
						|
 | 
						|
void NG_NetworkScene::ClearMessageMap(TMessageMap& map)
 | 
						|
{
 | 
						|
	// Release the messages in the map
 | 
						|
	for (int i = 0; i < map.size(); i++) {
 | 
						|
		vector<NG_NetworkMessage*>* msglist;
 | 
						|
		msglist = *(map.at(i));
 | 
						|
 | 
						|
		// Iterate through the current vector and release all it's messages
 | 
						|
		vector<NG_NetworkMessage*>::iterator msgit;
 | 
						|
		for (msgit = msglist->begin(); msgit != msglist->end(); msgit++) {
 | 
						|
			(*msgit)->Release();
 | 
						|
		}
 | 
						|
 | 
						|
		// Delete the actual vector
 | 
						|
		delete (msglist);
 | 
						|
	}
 | 
						|
 | 
						|
	// Empty the map
 | 
						|
	map.clear();
 | 
						|
}
 | 
						|
 |