/***************************************************************************
* Copyright (C) 2005 by the G System Team *
* http://www.g-system.at *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to *
* the following conditions: *
* *
* The above copyright notice and this permission notice shall be *
* included in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
* OTHER DEALINGS IN THE SOFTWARE. *
***************************************************************************/
#include "GClientFactory.h"
#include "GCommunicationWidget.h"
#include <GOpenGLFrame.h>
#include <GCamera.h>
#include <GDataController.h>
#include <GXmlDataController.h>
#include <GMoveAgent.h>
#include <GEnergyFormAgent.h>
#include <GVector3.h>
#include <GMatrix44.h>
#include <GElementID.h>
#include <GElement.h>
#include <GObject.h>
#include <GForm.h>
#include <GEnergy.h>
#include <qdom.h>
#include <qgl.h>
#include <qframe.h>
#include <qlayout.h>
#include <qgroupbox.h>
#include <qsplitter.h>
#include <qtimer.h>
#include <qtooltip.h>
#include <kmainwindow.h>
#include <klistbox.h>
#include <klineedit.h>
#include <ktextedit.h>
GClientFactory::GClientFactory(QObject* parent, const char* name)
: QObject(parent, name),
WorldEngineController(NULL),
MainFrame(NULL),
Frame(NULL),
Camera(NULL)
{
connect(&CheckTimer,SIGNAL(timeout()),this,SLOT(checkWorldEngineReady()));
}
GClientFactory::~GClientFactory()
{
}
void GClientFactory::renderInitStatus()
{
if (this->Frame)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDisable(GL_LIGHTING);
// Frame->qglColor(QColor(0,255,255)); //yellow
glColor4f(0,1,1,1);
Frame->renderText(Frame->width()/2-70, Frame->height()/2-5, "Connecting to the G Universe...");
glEnable(GL_LIGHTING);
glFlush();
}
}
void GClientFactory::checkWorldEngineReady()
{
if (GCS::GElementID::countFreeIDs() > 0)
{
CheckTimer.stop();
//finalize initialization (create client "element") and start rendering
qDebug("ID is now available, creating user element");
qDebug("Getting free ID");
GCS::GElementID user_id(GCS::GElementID::getFreeID());
GCS::GForm* user_form = new GCS::GForm(GCS::GVector3(10,10,10));
qDebug("Creating Element");
GCS::GElement* client_element =
new GCS::GElement(
new GCS::GObject(new GCS::GEnergy(5,0.1,10),
user_form,
GCS::GElementID(1), //galaxy as parent
GCS::GElementID(user_id), //own ID
GCS::GElementID(1), //connect to the parent (connectionID is the same as ID of the galaxy element)
new QDomDocument(),
this->WorldEngineController->getDataController()));
Q_CHECK_PTR(client_element);
qDebug("Creating agents and connecting user element to camera");
GBE::GMoveAgent* move_agent = new GBE::GMoveAgent();
QObject::connect(Camera,SIGNAL(translationSpeedImpulse(const GCS::GVector3& )),move_agent,SLOT(addTranslationSpeedImpulse(const GCS::GVector3& )));
QObject::connect(Camera,SIGNAL(rotationSpeedImpulse(const GCS::GVector3& )),move_agent,SLOT(addRotationImpulse(const GCS::GVector3& )));
QObject::connect(Camera,SIGNAL(stopMovement()),move_agent,SLOT(fullStop()));
client_element->addAgent(move_agent);
move_agent->initSlowDownFactor(0.5);
move_agent->initUpdateInterval(50);
GBE::GEnergyFormAgent* form_agent = new GBE::GEnergyFormAgent();
client_element->addAgent(form_agent);
this->Camera->setForm(user_form);
this->Camera->setFrame(Frame);
this->Camera->setViewDistance(2000);
this->Camera->setSpeedFactor(2);
this->Camera->startCamera();
qDebug("Adding user element to world engine");
this->WorldEngineController->getDataController()->add(client_element);
client_element->executeElement();
qDebug("Simulate a reparent event which produces a reparent message in the GWE");
//this will generate a proper reparented signal which is handled by
//the GWE which propagates a proper reparenting message to the parent - the universe element
// client_element->reparent(GCS::GElementID(0),GCS::GElementID(1),GCS::GMatrix44::createIdentityMatrix());
qDebug("Beginning rendering in user interface");
Frame->ViewProperties.CameraElement = user_id;
Frame->addTopElement(GCS::GElementID(1));
// Frame->startRendering(15); //already done in init()
disconnect(Frame,SIGNAL(afterRendering()),this,SLOT(renderInitStatus()));
QTimer* listupdater = new QTimer(this->MainFrame,"serverlistupdater");
connect(listupdater,SIGNAL(timeout()),this,SLOT(updateServerList()));
listupdater->start(4013);
}
}
/**
* @todo This is a dirty mess, but it's experimental anyway
* As soon as a the interface looks the way it should,
* a separate client interface class should be created
* since most of the things here are not the job of a
* factory.
*/
void GClientFactory::init(GWE::GweController* controller)
{
this->WorldEngineController = controller;
GWE::GDataController* dc = controller->getDataController();
this->MainFrame = new QFrame(NULL,"gclientwindow"); //KMainWindow is rather nasty, connects its own signals for quitting the application
this->MainFrame->resize(790,580); //fit to 800x600 (consider window decoration,...)
QGridLayout* mainlayout = new QGridLayout(MainFrame,1,1,4,4,"mainlayout");
QSplitter* framecommsplitter = new QSplitter(Qt::Vertical,MainFrame,"framecommsplitter");
mainlayout->addWidget(framecommsplitter,0,0);
//create the 3D client interface, this is were everything is displayed
this->Frame = new GCE::GOpenGLFrame(controller,framecommsplitter,"openglframe");
this->Frame->setFocusPolicy(QWidget::StrongFocus);
this->Frame->setFocus();
//communication widget
CommWidget = new GCommunicationWidget(framecommsplitter,"comm frame");
// layout->addWidget(framecommsplitter,1,0);
// this->Frame->setCaption("G Universe Client");
//frame initialization
Frame->resizeGL(640,480);
Frame->resize(640,480);
Frame->initializeGL();
Frame->ViewProperties.NearClippingPlane = 1;
Frame->ViewProperties.FarClippingPlane = 10000; //reduce this if you have slow rendering
Frame->ViewProperties.ViewPosition.z = 0.5;
Frame->ViewProperties.ViewTarget = GCS::GVector3(0,0,0);
Frame->ViewProperties.update();
MainFrame->show();
if (dc->inherits("GWE::GXmlDataController"))
{
GWE::GXmlDataController* xdc = (GWE::GXmlDataController*)dc;
qDebug("XML Data Controller found, connecting signals and slots for user messages");
connect(xdc,SIGNAL(userMessageReceived(QString, QString, bool )),CommWidget,SLOT(receiveMessage(QString, QString, bool )));
connect(CommWidget,SIGNAL(sendMessage(QString, QString )),xdc,SLOT(sendUserMessage(QString, QString )));
connect(xdc,SIGNAL(serverPresenceChanged(QString, bool, bool )),CommWidget,SLOT(updateContactState(QString, bool, bool )));
}
else
{
CommWidget->hide();
qWarning("No network capable data controller found, sending user messages is not possible!");
}
//create a camera, the camera will work on the view properties of the frame
this->Camera = new GCE::GCamera(Frame);
connect(Frame,SIGNAL(afterRendering()),this,SLOT(renderInitStatus()));
Frame->startRendering();
//periodically checks checkWorldEngineReady()
CheckTimer.start(500);
}
/*
void GClientFactory::prepareMessageForSending()
{
if (this->MessageText->text().isEmpty() || this->MessageDestination->text().isEmpty())
{
qWarning("Not sending message, message text and/or destination empty.");
return;
}
QString dest = this->MessageDestination->text();
QString msg = this->MessageText->text();
qDebug("Sending User Message:");
qDebug(QString(" destination: %1").arg(dest));
qDebug(QString(" message: %1").arg(msg));
if (dest=="*")
{
//broadcast message
int n = this->ServerList->numRows();
for (int i=0; i<n; i++)
{
QString destination = this->ServerList->text(i);
if (!destination.isEmpty())
emit this->sendMessage(msg,destination);
}
this->MessageHistory->append(QString("SENT TO ALL: ") + msg);
this->MessageText->clear();
}
else
{
//ordinary mssage
emit this->sendMessage(msg,dest);
this->MessageHistory->append(QString("SENT TO ") + dest + ": " + msg);
this->MessageText->clear();
}
}
void GClientFactory::receiveMessage(QString message, QString sender, bool internal)
{
QString m;
if (!internal)
m.append("EXTERNAL: ");
m.append(sender);
m.append(": ");
m.append(message);
this->MessageHistory->append(m);
}
*/
void GClientFactory::updateServerList()
{
if (this->WorldEngineController!=NULL)
{
GWE::GDataController* dc = this->WorldEngineController->getDataController();
if (dc->inherits("GWE::GXmlDataController"))
{
GWE::GXmlDataController* xdc = (GWE::GXmlDataController*)dc;
// this->CommWidget->clearExternalContacts();
// this->CommWidget->clearInternalContacts();
this->CommWidget->replaceInternalContactList(xdc->getAllKnownServers());
// this->ServerList->insertStringList(xdc->getAllKnownServers());
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1