irrNetLite 2.1 [BETA]

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Yep IDs are the way to go.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Alright, I've got it. It's even in a 2nd thread now and works like a charm :)
Finally, I can set the updateTimeOut value to whatever I want without any drop in rendering speed.

Btw, thanks for the event pipeline idea, Brainsaw; it's very convenient that way.
Never take advice from someone who likes to give advice, so take my advice and don't take it.
Brainsaw
Posts: 1176
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

Post by Brainsaw »

I hope you share what you have created. I haven't (yet) touched multithreading in my private programs ;)
Dustbin::Games on the web: https://www.dustbin-online.de/

Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Of course, here it is. I've cut a lot of project related code in order to keep the relevant parts readable and added some comments (some might be trivial). It's not perfect in terms of coding style, though. So, have fun going const-crazy about it. :D

Dependencies: Boost Thread

A Note on using mutexes: I did some testing without any mutexes at all and couldn't produce any thread-related problems. However, better safe than sorry, right?

HEADER

Code: Select all

#ifndef CLASS_NETWORK_H_INC
#define CLASS_NETWORK_H_INC

#include <Irrlicht.h>
#include <IrrNet.h>
#include <boost/thread/thread.hpp>
#include <iostream>

enum E_PACKET_TYPE
{
  EPT_UNIT_BUILT,
  EPT_UNIT_MOVED,
  EPT_UNIT_ATTACKED
};

// received packets will be stored in one of these structs
// and added to an array
struct SSyncUnitBuilt
{
  SSyncUnitBuilt() :    packetType(EPT_UNIT_BUILT) { }
  E_PACKET_TYPE         packetType;

  irr::u32              unitType;
  irr::u32              unitID;
  irr::core::vector3df  unitPosition;
};

struct SSyncUnitMoved
{
  SSyncUnitMoved() :    packetType(EPT_UNIT_MOVED) { }
  E_PACKET_TYPE         packetType;

  irr::u32              unitID;
  irr::core::vector3df  unitNewPosition;
};

struct SSyncUnitAttacked
{
  SSyncUnitAttacked() : packetType(EPT_UNIT_ATTACKED) { }
  E_PACKET_TYPE         packetType;

  irr::u32              unitID;
  irr::u32              targetID;
};

class CNetwork : public irr::net::INetCallback
{
private :

  irr::net::INetManager *netManager;
  bool                  isHost;

  // thread object, can be deleted like a usual object
  // it's not the running thread itself, just a representation of it
  // if you delete this object without joining the thread first,
  // the thread becomes detached and cannot be stopped without another interuption point
  // check boost API for more information on this topic
  boost::thread         *netThread;

  // volatile is kinda the opposite to const and prevents a variable from
  // getting cached or compiler-optimized to "true"
  // in that case we might not be able to stop the thread
  volatile bool         netThreadRun;
  volatile irr::u32     updateTimeOut;

  // internally used to start stop etc
  void startNetThread();
  void stopNetThread();
  void update();

  void handlePacket        (irr::net::SInPacket& packet);

  // called in handlePacket
  void receiveUnitBuilt    (irr::net::SInPacket& packet);
  void receiveUnitMoved    (irr::net::SInPacket& packet);
  void receiveUnitAttacked (irr::net::SInPacket& packet);

public :

  CNetwork();
  ~CNetwork();

  void createServer();
  void createServer(irr::net::SNetParams &params);
  void createClient(irr::core::stringc address);
  void createClient(irr::core::stringc address, irr::net::SNetParams &params);

  // stops running thread and deletes netManager
  // call before creating a new server etc
  void reset();

  irr::net::INetManager* getNetManager()           { return netManager; }
  bool isServer()                                  { return isHost; }
  irr::u32 getUpdateTimeOut()                      { return updateTimeOut; }
  void setUpdateTimeOut(irr::u32 newUpdateTimeOut) { updateTimeOut = newUpdateTimeOut; }

  // this function processes all received packets
  // it could also be implemented in another class
  void sync();

  void sendPacket (SSyncUnitBuilt&    data);
  void sendPacket (SSyncUnitBuilt&    data, irr::u16 playerID);
  void sendPacket (SSyncUnitMoved&    data);
  void sendPacket (SSyncUnitMoved&    data, irr::u16 playerID);
  void sendPacket (SSyncUnitAttacked& data);
  void sendPacket (SSyncUnitAttacked& data, irr::u16 playerID);

  // received packets end up in one of these arrays
  irr::core::array<SSyncUnitBuilt>    syncQueueUnitBuilt;
  irr::core::array<SSyncUnitMoved>    syncQueueUnitMoved;
  irr::core::array<SSyncUnitAttacked> syncQueueUnitAttacked;

  // as a class member the mutex is used to ensure thread-safety
  // while accessing any data in this class by another thread (other than netThread)
  boost::mutex mutex;
};

#endif
CPP

Code: Select all

#include <CNetwork.h>

using namespace irr;
using namespace core;
using namespace gui;
using namespace io;
using namespace scene;
using namespace video;

CNetwork::CNetwork()
{
  netManager = NULL;
  isHost     = false;

  netThread     = NULL;
  netThreadRun  = false;
  updateTimeOut = 500;
}

CNetwork::~CNetwork()
{
  reset();
}

void CNetwork::startNetThread()
{
  stopNetThread();

  netThreadRun = true;

  // the newly created thread's entrypoint is update()
  netThread = new boost::thread(&CNetwork::update, this);
}

void CNetwork::stopNetThread()
{
  if (netThread)
  {
    netThreadRun = false;

        // HERE: netThread exits mainloop

    // join() waits for a thread to finish
    // not breaking the main loop first would make us wait forever :)
    netThread->join();

        // HERE: both threads are "one again"

    // never delete a running thread or it becomes detached
    delete netThread;
    netThread = NULL;
  }
}

void CNetwork::createServer()
{
  if (!netManager)
  {
    net::SNetParams temp;
    temp.connectionTimeout = 5000;
    temp.maxClients        = 1;
    temp.downBandwidth     = 0;
    temp.upBandwidth       = 0;

    netManager = net::createIrrNetServer(this, 45000, temp);
    netManager->setVerbose(false);
    isHost = true;

    startNetThread();
  }
}

void CNetwork::createServer(irr::net::SNetParams &params)
{
  if (!netManager)
  {
    netManager = net::createIrrNetServer(this, 45000, params);
    netManager->setVerbose(false);
    isHost = true;

    startNetThread();
  }
}

void CNetwork::createClient(irr::core::stringc address)
{
  if (!netManager)
  {
    net::SNetParams temp;
    temp.connectionTimeout = 5000;
    temp.maxClients        = 1;
    temp.downBandwidth     = 0;
    temp.upBandwidth       = 0;

    netManager = net::createIrrNetClient(this, address.c_str(), 45000, temp);
    netManager->setVerbose(false);
    isHost = false;

    startNetThread();
  }
}

void CNetwork::createClient(irr::core::stringc address, irr::net::SNetParams &params)
{
  if (!netManager)
  {
    netManager = net::createIrrNetClient(this, address.c_str(), 45000, params);
    netManager->setVerbose(false);
    isHost = false;

    startNetThread();
  }
}

void CNetwork::reset()
{
  stopNetThread();

  if (netManager)
  {
    delete netManager;
    netManager = NULL;
  }
}

// main loop
void CNetwork::update()
{
  while (netThreadRun)
  {
    if (netManager && netManager->getConnectionStatus() != net::EICS_FAILED)
    {
      netManager->update(updateTimeOut);
    }
  }
}

// usual packet handling
void CNetwork::handlePacket(irr::net::SInPacket& packet)
{
  c8 packetType;
  packet >> packetType;

  switch((E_PACKET_TYPE)packetType)
  {
    // pass accordingly
    case EPT_UNIT_BUILT    : { receiveUnitBuilt(packet);    } break;
    case EPT_UNIT_MOVED    : { receiveUnitMoved(packet);    } break;
    case EPT_UNIT_ATTACKED : { receiveUnitAttacked(packet); } break;
  }
}

// a lot of overloaded send functions
void CNetwork::sendPacket(SSyncUnitBuilt& data)
{
  net::SOutPacket packet;
  packet << (c8)data.packetType;
  packet << data.unitType;
  packet << data.unitID;
  packet << data.unitPosition;
  netManager->sendOutPacket(packet);
}

void CNetwork::sendPacket(SSyncUnitBuilt& data, irr::u16 playerID)
{
  net::SOutPacket packet;
  packet << (c8)data.packetType;
  packet << data.unitType;
  packet << data.unitID;
  packet << data.unitPosition;
  netManager->sendOutPacket(packet, playerID);
}

// receive functions access an array
void CNetwork::receiveUnitBuilt(irr::net::SInPacket& packet)
{
  // therefore we scope_lock the resources
  // a scoped_lock unlocks and destroys itself
  // as soon as the function returns
  boost::mutex::scoped_lock lock(mutex); // HERE: arrays are locked
  SSyncUnitBuilt temp;
  packet >> temp.unitType;
  packet >> temp.unitID;
  packet >> temp.unitPosition;

  // push_front to add packets in receive functions (netThread is slower)
  // getLast() and erase last in sync() (irrlicht thread is faster)
  // maintains order of packets received (first in, first out)
  syncQueueUnitBuilt.push_front(temp);
} // HERE: arrays are unlocked

void CNetwork::sendPacket(SSyncUnitMoved& data)
{
  net::SOutPacket packet;
  packet << (c8)data.packetType;
  packet << data.unitID;
  packet << data.unitNewPosition;
  netManager->sendOutPacket(packet);
}

void CNetwork::sendPacket(SSyncUnitMoved& data, irr::u16 playerID)
{
  net::SOutPacket packet;
  packet << (c8)data.packetType;
  packet << data.unitID;
  packet << data.unitNewPosition;
  netManager->sendOutPacket(packet, playerID);
}

void CNetwork::receiveUnitMoved(irr::net::SInPacket& packet)
{
  boost::mutex::scoped_lock lock(mutex);
  SSyncUnitMoved temp;
  packet >> temp.unitID;
  packet >> temp.unitNewPosition;
  syncQueueUnitMoved.push_front(temp);
}

void CNetwork::sendPacket(SSyncUnitAttacked& data)
{
  net::SOutPacket packet;
  packet << (c8)data.packetType;
  packet << data.unitID;
  packet << data.targetID;
  netManager->sendOutPacket(packet);
}

void CNetwork::sendPacket(SSyncUnitAttacked& data, irr::u16 playerID)
{
  net::SOutPacket packet;
  packet << (c8)data.packetType;
  packet << data.unitID;
  packet << data.targetID;
  netManager->sendOutPacket(packet, playerID);
}

void CNetwork::receiveUnitAttacked(irr::net::SInPacket& packet)
{
  boost::mutex::scoped_lock lock(mutex);
  SSyncUnitAttacked temp;
  packet >> temp.unitID;
  packet >> temp.targetID;
  syncQueueUnitAttacked.push_front(temp);
}

// test sync function to be called by irrlicht thread
// could be implemented anywhere
// mutex would look like that:   " boost::mutex::scoped_lock lock(pointerToCNetworkInstance->mutex); "
// call it as often as you want to check for new packets
// doesn't have to be each frame (once per sec is enough in my case)
//
// could be the other way around:
// use a function to notify irrlichtThread how many packets are waiting
// and pass them whenever you want
void CNetwork::sync()
{
  // again we lock our arrays
  boost::mutex::scoped_lock lock(mutex);

  // process and delete all received packets
  while (!syncQueueUnitBuilt.empty())
  {
    // iostream is not thread-safe
    // if you set netManager->setVerbose(true)
    // this might result in weird (mixed) output
    // to prevent this from happening we would need another mutex at global scope (not as a class member)
    // and lock that mutex as well

    // test output, getLast() item and process packets here
    std::cout << "----------" << std::endl;
    std::cout << "ARRAY ELEMENT # : " << syncQueueUnitBuilt.size() << std::endl;
    std::cout << "unitType : " << syncQueueUnitBuilt.getLast().unitType << std::endl;
    std::cout << "unitID : " << syncQueueUnitBuilt.getLast().unitID << std::endl;
    std::cout << "PosX : " << syncQueueUnitBuilt.getLast().unitPosition.X << std::endl;
    std::cout << "PosY : " << syncQueueUnitBuilt.getLast().unitPosition.Y << std::endl;
    std::cout << "PosZ : " << syncQueueUnitBuilt.getLast().unitPosition.Z << std::endl;

    // erase() last item
    if (syncQueueUnitBuilt.size() > 0)
    {
      syncQueueUnitBuilt.erase(syncQueueUnitBuilt.size() - 1);
    }
  }

  // same thing for all kinds of packets
  while (!syncQueueUnitMoved.empty())
  {
    std::cout << "----------" << std::endl;
    std::cout << "ARRAY ELEMENT # : " << syncQueueUnitMoved.size() << std::endl;
    std::cout << "unitID : " << syncQueueUnitMoved.getLast().unitID << std::endl;
    std::cout << "New PosX : " << syncQueueUnitMoved.getLast().unitNewPosition.X << std::endl;
    std::cout << "New PosY : " << syncQueueUnitMoved.getLast().unitNewPosition.Y << std::endl;
    std::cout << "New PosZ : " << syncQueueUnitMoved.getLast().unitNewPosition.Z << std::endl;

    if (syncQueueUnitMoved.size() > 0)
    {
      syncQueueUnitMoved.erase(syncQueueUnitMoved.size() - 1);
    }
  }

  while (!syncQueueUnitAttacked.empty())
  {
    std::cout << "----------" << std::endl;
    std::cout << "ARRAY ELEMENT # : " << syncQueueUnitAttacked.size() << std::endl;
    std::cout << "unitID : " << syncQueueUnitAttacked.getLast().unitID << std::endl;
    std::cout << "targetID : " << syncQueueUnitAttacked.getLast().targetID << std::endl;

    if (syncQueueUnitAttacked.size() > 0)
    {
      syncQueueUnitAttacked.erase(syncQueueUnitAttacked.size() - 1);
    }
  }
}
Never take advice from someone who likes to give advice, so take my advice and don't take it.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Nice contribution Bate, it seems well contained so I'll think about including it as part of the package maybe as an add-on.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Cool, I'm sure it would be useful (it took me quite a while to figure everything out, hehe).
Never take advice from someone who likes to give advice, so take my advice and don't take it.
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Found a small issue:

Code: Select all

/// This gets the number of players connected. This is only valid for servers.
const u32 CNetManager::getPeerCount()
{
  return (u32)host->peerCount;
}

Code: Select all

ENetHost Struct:

size_t peerCount
number of peers allocated for this host
That's why getPeerCount() actually returns SNetParams::maxClients + 1 instead of the number of players connected.

Fix:

Code: Select all

const u32 CNetManager::getPeerCount()
{
  u32 count = 0;

  for (u32 i = 1; i < netParams.maxClients; ++i)
  {
    if (players[i])
    {
      ++count;
    }
  }

  return count;
}
Never take advice from someone who likes to give advice, so take my advice and don't take it.
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

How would I implement a bool type in SPacket, 1 byte just as u8?

Code: Select all

void SInPacket::operator >> (bool &data)
{
	memcpy(&data,getData()+pos,1);
	pos++;
}

SOutPacket& SOutPacket::operator << (const bool data)
{
	enlargeBuffer(1);
	memcpy(buff.pointer() + buff.size() - 1, &data, 1);
	return *this;
}
Never take advice from someone who likes to give advice, so take my advice and don't take it.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Another way you can do it is maybe encoding 8 bools in one byte. Something like:

Code: Select all

union BitEncode
{
	struct BitPack
	{
			int bit1:1;
			int bit2:1;
			int bit3:1;
			int bit4:1;
			int bit5:1;
			int bit6:1;
			int bit7:1;
			int bit8:1;
	} bitPack;

	char byte;
};

Then modify like so:

BitEncode eU;

eU.bitPack.bit1 = 1;
eU.bitPack.bit2 = 0;
eU.bitPack.bit3 = 0;
eU.bitPack.bit4 = 1;
eU.bitPack.bit5 = 1;
eU.bitPack.bit6 = 1;
eU.bitPack.bit7 = 0;
eU.bitPack.bit8 = 1;

and store as byte:

packet << eU.byte;
Hope that helps.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

That's more economical, thanks.
Never take advice from someone who likes to give advice, so take my advice and don't take it.
Murloc992
Posts: 272
Joined: Mon Apr 13, 2009 2:45 pm
Location: Utena,Lithuania

Post by Murloc992 »

When trying to build any of the examples of this, I am getting errors like:

Code: Select all

Linking console executable: bin/Debug/INETLite Example1
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(host.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(list.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(memory.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(packet.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(peer.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(protocol.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(unix.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(compress.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(deflate.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(trees.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(uncompr.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(zutil.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(adler32.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(crc32.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(inflate.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(inftrees.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../libs/irrNetLite/lib/libirrnet.a(inffast.o)' is incompatible with i386 output
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings
Lib was built using Linux Makefile and I am using C::B 10.05.

Any advices? :?
RobbyRob
Posts: 21
Joined: Fri Mar 02, 2007 4:30 pm
Location: Germany

IrrNEtLite Problems with "make" for Linux

Post by RobbyRob »

Hi,

I am trying to compile IrrNEtLite Version 2.1Beta on my Linux Ubuntu 9.4; when I go to /source and type in the console "make" I got following Error message:

Code: Select all

robert@robert-desktop:~/Downloads/irrNetLite/source$ make
Makefile:45: *** missing separator.  Schluss.
Anybody an idea what that means?
Line 45 of makefile is:

Code: Select all

withirrlicht:
CXXINCS += -Iirrlicht/include -DCOMPILE_WITH_IRRLICHT
all staticlib clean
would appreciate any help,

Thank`s


Robert
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

This seems like an illegal makefile. withirrlicht: is a target, which would require the subtargets in the dependencies after the colon. The variable setting, which is probably dependant on the target, needs to be put after the colon as well. Use a different target for this variable setting and make it first dependency of the withirrlicht: target. It's possible that there are make versions which support this kind of makefiles, but it's not really portable.
mataanjin
Posts: 19
Joined: Tue May 25, 2010 3:07 am

Post by mataanjin »

i'm try to combine this with irrlicht.
i try to make a simple window, with 2 button, 1 for server and the other for client.

and here is the code

Code: Select all

#include <irrlicht.h>
#include <irrNet.h>
#include <iostream>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "irrNetLite.lib")
#pragma comment(lib, "ws2_32.lib")

struct SAppContext
{
	IrrlichtDevice *device;
	s32				counter;
};
enum
{
	GUI_ID_QUIT_BUTTON = 101,
	GUI_ID_NEW_WINDOW_BUTTON,
	GUI_ID_FILE_OPEN_BUTTON,
	GUI_ID_TRANSPARENCY_SCROLL_BAR
};

net::INetManager* netManager = 0;
IGUIEnvironment* env = 0;
s32 gameState;

class MyNetCallback : public net::INetCallback
{
public:
	virtual void handlePacket(net::SInPacket& packet)
	{
		packet.decryptPacket("hushthisissecret");
		packet.deCompressPacket();
		core::stringc str;
		packet >> str;

		core::vector3df vec;
		packet >> vec;
		
		f32 height;
		packet >> height;
		
		std::cout << "Message: " << str.c_str();
		std::cout << " Position: " << vec.X << " " << vec.Y << " " << vec.Z;
		std::cout << " Height: " << height << " ft";
		std::cout << std::endl;
	}
};

void ServerSide()
{
	MyNetCallback* netCallback = new MyNetCallback();
	net::INetManager* netManager = net::createIrrNetServer(netCallback);
	netManager->setVerbose(true);

	if(netManager->getConnectionStatus() != net::EICS_FAILED)
		gameState = 1;
}

void ClientSide()
{
	env->addButton(rect<s32>(10,320,110,320 + 32), 0, GUI_ID_FILE_OPEN_BUTTON, L"Kirim", L"Kirim Data");

	net::INetManager* netManager = net::createIrrNetClient(0, "127.0.0.1");
	netManager->setVerbose(true);

	if (netManager->getConnectionStatus() != net::EICS_FAILED)
		gameState = 2;
}

class MyEventReceiver : public IEventReceiver
{
public:
	MyEventReceiver(SAppContext & context) : Context(context) { }

	virtual bool OnEvent(const SEvent& event)
	{
		
		s32 id = event.GUIEvent.Caller->getID();
		IGUIEnvironment* env = Context.device->getGUIEnvironment();

		switch(id)
		{
		case GUI_ID_QUIT_BUTTON:
			ServerSide();
			return true;

		case GUI_ID_NEW_WINDOW_BUTTON:
			ClientSide();
			return true;

		case GUI_ID_FILE_OPEN_BUTTON:
			{
				net::SOutPacket packet;
				packet << "Test Message";
				packet << core::vector3df(50.0f, 30.0f, 20.0f) << 50.0f;		
				packet.compressPacket();
				packet.encryptPacket("hushthisissecret");
				netManager->sendOutPacket(packet);
			}
			return true;

		default:
			return false;
		}

		return false;
	}

private:
	SAppContext & Context;
};

int main()
{
	IrrlichtDevice * device = createDevice(video::EDT_DIRECT3D8, core::dimension2d<u32>(640, 480));
	if (device == 0)
		return 1;

	device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
	device->setResizable(true);

	video::IVideoDriver* driver = device->getVideoDriver();
	IGUIEnvironment* env = device->getGUIEnvironment();

	IGUISkin* skin = env->getSkin();
	IGUIFont* font = env->getFont("D:/Game Development/Engine/media/fonthaettenschweiler.bmp");
	if (font)
		skin->setFont(font);

	skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);

	env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_QUIT_BUTTON,
			L"Server", L"Jadi Server");
	env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_NEW_WINDOW_BUTTON,
			L"Client", L"Jadi Client");
	
	SAppContext context;
	context.device = device;
	context.counter = 0;
	MyEventReceiver receiver(context);
	device->setEventReceiver(&receiver);

	gameState = 0;

	while(device->run() && driver)
	{
		if (device->isWindowActive())
		{
			if ( gameState != 0 )
			{
				if ( netManager->getConnectionStatus() != net::EICS_FAILED )
					netManager->update(1000);
				else
				{
					delete netManager;
					gameState = 0;
				}
			}
			driver->beginScene(true, true, SColor(0,200,200,200));

			env->drawAll();
	
			driver->endScene();
		}
	}

	device->drop();
	return 0;
}
and it always stop at this
s32 id = event.GUIEvent.Caller->getID();
with this error.

Code: Select all

'dada.exe': Loaded 'D:\a\dada\Debug\dada.exe', Symbols loaded.
'dada.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\msvcp100d.dll', Symbols loaded.
'dada.exe': Loaded 'C:\Windows\SysWOW64\msvcr100d.dll', Symbols loaded.
'dada.exe': Loaded 'D:\a\dada\Irrlicht.dll', Binary was not built with debug information.
'dada.exe': Loaded 'C:\Windows\SysWOW64\user32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\gdi32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\lpk.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\usp10.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\msvcrt.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\advapi32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\sechost.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\rpcrt4.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\sspicli.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\cryptbase.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\opengl32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\glu32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\ddraw.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\dciman32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\setupapi.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\cfgmgr32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\oleaut32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\ole32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\devobj.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\dwmapi.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\winmm.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\ws2_32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\nsi.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\imm32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\msctf.dll', Cannot find or open the PDB file
Irrlicht Engine version 1.7.2
Microsoft Windows 7 Ultimate Edition  (Build 7600)
'dada.exe': Loaded 'C:\Windows\SysWOW64\uxtheme.dll', Cannot find or open the PDB file
Using renderer: Direct3D 8.1
'dada.exe': Loaded 'C:\Windows\SysWOW64\d3d8.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\version.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\d3d8thk.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\nvd3dum.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\powrprof.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Program Files (x86)\NVIDIA Corporation\3D Vision\nvSCPAPI.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\shell32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\shlwapi.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\nvapi.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\wintrust.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\crypt32.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\msasn1.dll', Cannot find or open the PDB file
'dada.exe': Unloaded 'C:\Windows\SysWOW64\powrprof.dll'
'dada.exe': Unloaded 'C:\Windows\SysWOW64\nvd3dum.dll'
NVIDIA GeForce 8800 GTS 512 nvd3dum.dll 8.17.12.6089
'dada.exe': Loaded 'C:\Windows\SysWOW64\nvd3dum.dll', Cannot find or open the PDB file
'dada.exe': Loaded 'C:\Windows\SysWOW64\powrprof.dll', Cannot find or open the PDB file
First-chance exception at 0x00c8763e in dada.exe: 0xC0000005: Access violation reading location 0x000000f1.
Unhandled exception at 0x00c8763e in dada.exe: 0xC0000005: Access violation reading location 0x000000f1.
The program '[2800] dada.exe: Native' has exited with code -1073741819 (0xc0000005).
so how can i fix this?
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Post by zerochen »

hi
try to add

Code: Select all

switch(event.EventType)
{ 
case EET_GUI_EVENT: s32 id = event.GUIEvent.Caller->getID();
                                 ... break;
}
to ensure that a gui event is happend and not a key event or someting like that
Post Reply