Add internal command interpretation
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
|
||||
//std
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
|
||||
//thread
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
// Vendor
|
||||
#include <yojimbo.h>
|
||||
|
||||
@@ -18,7 +24,22 @@ static GameServer *serv;
|
||||
|
||||
void interrupt_handler(int /*dummy*/)
|
||||
{
|
||||
serv->m_running = false;
|
||||
serv->dispatchCommand("stop");
|
||||
}
|
||||
|
||||
void ReadCin(std::atomic<bool> &run)
|
||||
{
|
||||
std::string buffer;
|
||||
|
||||
while (run.load())
|
||||
{
|
||||
std::getline(std::cin, buffer);
|
||||
serv->dispatchCommand(buffer);
|
||||
if (buffer == "stop")
|
||||
{
|
||||
run.store(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -29,12 +50,13 @@ int main(int argc, char *argv[])
|
||||
DWORD prev_mode;
|
||||
hInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hInput, &prev_mode);
|
||||
SetConsoleMode(hInput, prev_mode & ENABLE_EXTENDED_FLAGS);
|
||||
prev_mode &= ~ENABLE_QUICK_EDIT_MODE;
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
#endif
|
||||
|
||||
if (!InitializeYojimbo())
|
||||
{
|
||||
printf("error: failed to initialize Yojimbo!\n");
|
||||
std::cout << "error: failed to initialize Yojimbo!" << std::endl;
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
yojimbo_log_level(YOJIMBO_LOG_LEVEL_INFO);
|
||||
@@ -45,8 +67,15 @@ int main(int argc, char *argv[])
|
||||
yojimbo::Address addr(127, 0, 0, 1, 9999);
|
||||
GameServer server(addr);
|
||||
serv = &server; //For interrupt
|
||||
|
||||
std::atomic<bool> run(true);
|
||||
std::thread cinThread(ReadCin, std::ref(run));
|
||||
|
||||
server.Run();
|
||||
|
||||
run.store(false);
|
||||
cinThread.join();
|
||||
|
||||
ShutdownYojimbo();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <memory>
|
||||
|
||||
//own
|
||||
#include "messages/Command.h"
|
||||
#include "core/Components.h"
|
||||
|
||||
using namespace yojimbo;
|
||||
@@ -86,12 +85,32 @@ void GameServer::Update(float dt)
|
||||
ProcessMessages();
|
||||
|
||||
// ... process client inputs ...
|
||||
this->m_commandQueueMutex.lock(); //As long as the server is processing the que the adding is blocked
|
||||
while (!this->commandQueue.empty())
|
||||
{
|
||||
std::unique_ptr<Command> command_ptr = std::move(commandQueue.front());
|
||||
commandQueue.pop();
|
||||
command_ptr->execute(this);
|
||||
}
|
||||
this->m_commandQueueMutex.unlock();
|
||||
|
||||
// ... update game ...
|
||||
// ... send game state to clients ...
|
||||
|
||||
m_server.SendPackets();
|
||||
}
|
||||
|
||||
void GameServer::dispatchCommand(std::string commandStr) //thread safe
|
||||
{
|
||||
std::unique_ptr<Command> u_ptr(Command::create(commandStr));
|
||||
if (u_ptr)
|
||||
{
|
||||
this->m_commandQueueMutex.lock();
|
||||
this->commandQueue.push(std::move(u_ptr));
|
||||
this->m_commandQueueMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void GameServer::ProcessMessages()
|
||||
{
|
||||
for (int i = 0; i < MAX_PLAYERS; i++)
|
||||
@@ -106,7 +125,9 @@ void GameServer::ProcessMessages()
|
||||
std::unique_ptr<Command> command(Command::create(i, message));
|
||||
if (command)
|
||||
{
|
||||
command->execute(this);
|
||||
this->m_commandQueueMutex.lock();
|
||||
this->commandQueue.push(std::move(command));
|
||||
this->m_commandQueueMutex.unlock();
|
||||
}
|
||||
m_server.ReleaseMessage(i, message);
|
||||
message = m_server.ReceiveMessage(i, j);
|
||||
|
||||
@@ -4,17 +4,22 @@
|
||||
//Std
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
//Vendor
|
||||
#include <yojimbo.h>
|
||||
#include <entityx/entityx.h>
|
||||
|
||||
class GameServer;
|
||||
|
||||
//Own
|
||||
#include "Shared.h"
|
||||
#include "messages/Command.h"
|
||||
|
||||
static const int MAX_PLAYERS = 64;
|
||||
|
||||
class GameServer;
|
||||
|
||||
|
||||
class ServerAdapter : public SharedAdapter
|
||||
{
|
||||
@@ -37,20 +42,21 @@ public:
|
||||
void ClientConnected(int clientIndex);
|
||||
void ClientDisconnected(int clientIndex);
|
||||
|
||||
void ProcessCommand(std::string command);
|
||||
void dispatchCommand(std::string commandStr); //thread safe
|
||||
void ProcessMessages();
|
||||
void ProcessMessage(int clientIndex, yojimbo::Message *message);
|
||||
|
||||
void Run();
|
||||
void Update(float dt);
|
||||
|
||||
bool m_running;
|
||||
|
||||
std::queue<std::unique_ptr<Command>> commandQueue;
|
||||
entityx::EntityX ex;
|
||||
std::map<int, entityx::Entity> serverToEntityX;
|
||||
|
||||
private:
|
||||
double m_time;
|
||||
std::mutex m_commandQueueMutex;
|
||||
|
||||
GameConnectionConfig m_connectionConfig;
|
||||
ServerAdapter m_adapter;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "../Shared.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
Command *Command::create(int clientIndex, yojimbo::Message *message)
|
||||
{
|
||||
@@ -9,13 +10,28 @@ Command *Command::create(int clientIndex, yojimbo::Message *message)
|
||||
{
|
||||
case (int)GameMessageType::TEST:
|
||||
return new TestCommand(clientIndex, message);
|
||||
break;
|
||||
case (int)GameMessageType::SETNAME:
|
||||
return new SetNameCommand(clientIndex, message);
|
||||
break;
|
||||
default:
|
||||
std::cout << "Unknown message type received!" << std::endl;
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Command *Command::create(std::string command)
|
||||
{
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >>
|
||||
token;
|
||||
if (token == "stop")
|
||||
{
|
||||
return new StopCommandInternal();
|
||||
}
|
||||
else if (token == "test")
|
||||
{
|
||||
return new TestCommandInternal();
|
||||
}
|
||||
std::cout << "Internal commando don't exists: " << command << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
//Vendor
|
||||
#include <yojimbo.h>
|
||||
|
||||
class Command;
|
||||
#include "../GameServer.h"
|
||||
|
||||
// ---- Interface:
|
||||
@@ -12,33 +14,53 @@ public:
|
||||
// Create Commands from Network messages (Limited list)
|
||||
static Command *create(int clientIndex, yojimbo::Message *message);
|
||||
// Create Commands from Strings (Limited list)
|
||||
static Command *create(std::string);
|
||||
|
||||
virtual void execute(GameServer *server) = 0;
|
||||
};
|
||||
|
||||
// --- implemented Classes:
|
||||
// --- Classes Network:
|
||||
|
||||
class TestCommand : public Command
|
||||
{
|
||||
public:
|
||||
TestCommand(int clientIndex, yojimbo::Message *message)
|
||||
: m_clientIndex(clientIndex), m_message((TestMessage *)message) {}
|
||||
: m_clientIndex(clientIndex),
|
||||
m_data(((TestMessage *)message)->m_data)
|
||||
{}
|
||||
|
||||
virtual void execute(GameServer *server) override;
|
||||
|
||||
private:
|
||||
int m_clientIndex;
|
||||
TestMessage *m_message;
|
||||
int m_data;
|
||||
};
|
||||
|
||||
class SetNameCommand : public Command
|
||||
{
|
||||
public:
|
||||
SetNameCommand(int clientIndex, yojimbo::Message *message)
|
||||
: m_clientIndex(clientIndex), m_message((SetNameMessage *)message) {}
|
||||
: m_clientIndex(clientIndex),
|
||||
m_name(std::string(((SetNameMessage *)message)->buffer))
|
||||
{}
|
||||
|
||||
virtual void execute(GameServer *server) override;
|
||||
|
||||
private:
|
||||
int m_clientIndex;
|
||||
SetNameMessage *m_message;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
// --- Classes Internal:
|
||||
|
||||
class TestCommandInternal : public Command
|
||||
{
|
||||
public:
|
||||
virtual void execute(GameServer *server) override;
|
||||
};
|
||||
|
||||
class StopCommandInternal : public Command
|
||||
{
|
||||
public:
|
||||
virtual void execute(GameServer *server) override;
|
||||
};
|
||||
@@ -8,7 +8,7 @@ void SetNameCommand::execute(GameServer *server)
|
||||
entityx::ComponentHandle<NetworkPlayerProperties> playerproperties = entity.component<NetworkPlayerProperties>();
|
||||
if (playerproperties)
|
||||
{
|
||||
playerproperties->name = std::string(m_message->buffer);
|
||||
playerproperties->name = m_name;
|
||||
}
|
||||
std::cout << "Entity name changed to " << playerproperties->name << " Buffer content: " << std::string(m_message->buffer) << std::endl;
|
||||
std::cout << "Entity name changed to " << playerproperties->name << " Buffer content: " << m_name << std::endl;
|
||||
}
|
||||
6
src/messages/StopCommandInternal.cpp
Normal file
6
src/messages/StopCommandInternal.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "Command.h"
|
||||
|
||||
void StopCommandInternal::execute(GameServer *server)
|
||||
{
|
||||
server->m_running = false;
|
||||
}
|
||||
@@ -8,5 +8,5 @@ void TestCommand::execute(GameServer *server)
|
||||
entityx::Entity entity = server->serverToEntityX.at(m_clientIndex);
|
||||
entityx::ComponentHandle<NetworkPlayerProperties> playerproperties = entity.component<NetworkPlayerProperties>();
|
||||
|
||||
std::cout << "Test message received from client " << playerproperties->name << ":" << m_clientIndex << " with data: " << m_message->m_data << std::endl;
|
||||
std::cout << "Test message received from client " << playerproperties->name << ":" << m_clientIndex << " with data: " << m_data << std::endl;
|
||||
}
|
||||
|
||||
8
src/messages/TestCommandInternal.cpp
Normal file
8
src/messages/TestCommandInternal.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "Command.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void TestCommandInternal::execute(GameServer *server)
|
||||
{
|
||||
std::cout << "Internal testcommand launched!" << std::endl;
|
||||
}
|
||||
Reference in New Issue
Block a user