server open and event loop
This commit is contained in:
parent
2be3549b49
commit
0e8e41e4fb
7 changed files with 141 additions and 114 deletions
|
@ -35,7 +35,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
include_directories(${OPENGL_INCLUDE_DIR})
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/libs/glm/)
|
include_directories(${CMAKE_SOURCE_DIR}/libs/glm/)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/libs/asio/asio/include/)
|
||||||
|
|
||||||
add_executable(game ${GAME_SRC} ${GAME_HEADERS})
|
add_executable(game ${GAME_SRC} ${GAME_HEADERS})
|
||||||
setup_target(game)
|
setup_target(game)
|
||||||
target_link_libraries(game X11 epoxy)
|
target_link_libraries(game X11 epoxy pthread)
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
#include "opengl.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <asio.hpp>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "opengl.hpp"
|
||||||
#include "game_window.hpp"
|
#include "game_window.hpp"
|
||||||
|
#include "server.hpp"
|
||||||
#include "options.hpp"
|
#include "options.hpp"
|
||||||
|
|
||||||
uint64_t optionsFlags;
|
uint64_t optionsFlags;
|
||||||
|
|
||||||
|
|
||||||
|
using asio::ip::tcp;
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
|
||||||
|
char port[]="3490";
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
|
@ -56,8 +63,16 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asio::io_service io_service;
|
||||||
|
Server s(io_service, atoi(port) );
|
||||||
|
|
||||||
GameWindow window(500, 500);
|
GameWindow window(500, 500);
|
||||||
window.set_maxfps(60.0);
|
window.set_maxfps(60.0);
|
||||||
window.loop();
|
|
||||||
window.stop();
|
while(window.running()){
|
||||||
|
window.poll();
|
||||||
|
io_service.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,18 +101,11 @@ void endofthejedi::GLWindow::handle(XEvent event) {
|
||||||
|
|
||||||
void endofthejedi::GLWindow::swap() { glXSwapBuffers(m_display, m_window); }
|
void endofthejedi::GLWindow::swap() { glXSwapBuffers(m_display, m_window); }
|
||||||
|
|
||||||
void endofthejedi::GLWindow::loop() {
|
void endofthejedi::GLWindow::poll() {
|
||||||
m_running = true;
|
|
||||||
|
|
||||||
timespec prev;
|
clock_gettime(CLOCK_MONOTONIC_RAW, &prev);
|
||||||
timespec current;
|
clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &prev);
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);
|
|
||||||
|
|
||||||
double delta = 0.0;
|
|
||||||
double sleeptime = 0.0;
|
|
||||||
|
|
||||||
while (m_running) {
|
|
||||||
handleevents();
|
handleevents();
|
||||||
render(delta);
|
render(delta);
|
||||||
swap();
|
swap();
|
||||||
|
@ -132,11 +125,10 @@ void endofthejedi::GLWindow::loop() {
|
||||||
m_fps = (1000000000.0/delta);
|
m_fps = (1000000000.0/delta);
|
||||||
//std::cout << m_fps << "\n";
|
//std::cout << m_fps << "\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void endofthejedi::GLWindow::stop() { m_running = false; }
|
void endofthejedi::GLWindow::stop() { m_running = false; }
|
||||||
|
bool endofthejedi::GLWindow::running() { return m_running; }
|
||||||
void endofthejedi::GLWindow::init() {}
|
void endofthejedi::GLWindow::init() { m_running = true; }
|
||||||
void endofthejedi::GLWindow::render(double time) { UNUSED(time) }
|
void endofthejedi::GLWindow::render(double time) { UNUSED(time) }
|
||||||
void endofthejedi::GLWindow::resize() {}
|
void endofthejedi::GLWindow::resize() {}
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
namespace endofthejedi {
|
namespace endofthejedi {
|
||||||
|
|
||||||
class GLWindow {
|
class GLWindow {
|
||||||
private:
|
private:
|
||||||
//X-related stuff
|
//X-related stuff
|
||||||
Display* m_display;
|
Display* m_display;
|
||||||
Window m_rootwnd;
|
Window m_rootwnd;
|
||||||
GLint m_attributes[23] =
|
GLint m_attributes[23] =
|
||||||
{
|
{
|
||||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||||
|
@ -29,17 +29,21 @@ class GLWindow {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
XVisualInfo* m_visualinfo;
|
XVisualInfo* m_visualinfo;
|
||||||
Colormap m_colormap;
|
Colormap m_colormap;
|
||||||
XSetWindowAttributes m_swa;
|
XSetWindowAttributes m_swa;
|
||||||
Window m_window;
|
Window m_window;
|
||||||
GLXContext m_glcontext;
|
GLXContext m_glcontext;
|
||||||
XWindowAttributes m_gwa;
|
XWindowAttributes m_gwa;
|
||||||
Atom m_atomWmDeleteWindow;
|
Atom m_atomWmDeleteWindow;
|
||||||
//End of X related stuff
|
//End of X related stuff
|
||||||
|
|
||||||
unsigned int m_width;
|
unsigned int m_width;
|
||||||
unsigned int m_height;
|
unsigned int m_height;
|
||||||
|
double delta = 0.0;
|
||||||
|
double sleeptime = 0.0;
|
||||||
|
timespec prev;
|
||||||
|
timespec current;
|
||||||
|
|
||||||
//mainloop condition
|
//mainloop condition
|
||||||
bool m_running = false;
|
bool m_running = false;
|
||||||
|
@ -48,9 +52,7 @@ class GLWindow {
|
||||||
//if maxfps = 0 there's no fps limit
|
//if maxfps = 0 there's no fps limit
|
||||||
double m_maxfps;
|
double m_maxfps;
|
||||||
|
|
||||||
void handleevents();
|
protected:
|
||||||
|
|
||||||
protected:
|
|
||||||
//ancestors shall override these methods
|
//ancestors shall override these methods
|
||||||
virtual void init();
|
virtual void init();
|
||||||
//called by mainloop periodically
|
//called by mainloop periodically
|
||||||
|
@ -62,16 +64,19 @@ class GLWindow {
|
||||||
//as it handles the close calls & resizing
|
//as it handles the close calls & resizing
|
||||||
virtual void handle(XEvent event);
|
virtual void handle(XEvent event);
|
||||||
|
|
||||||
|
virtual void handleevents();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//initializes the X Window & creates an OpenGL context
|
//initializes the X Window & creates an OpenGL context
|
||||||
GLWindow(unsigned int width, unsigned int height);
|
GLWindow(unsigned int width, unsigned int height);
|
||||||
~GLWindow();
|
~GLWindow();
|
||||||
|
|
||||||
//mainloop does event handling & calls render/swap
|
//mainloop does event handling & calls render/swap
|
||||||
void loop();
|
void poll();
|
||||||
void swap();
|
void swap();
|
||||||
//stops the mainloop by setting m_running false
|
//stops the mainloop by setting m_running false
|
||||||
void stop();
|
void stop();
|
||||||
|
bool running();
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
unsigned int getheight() const {
|
unsigned int getheight() const {
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
#include "server.hpp"
|
|
||||||
|
|
||||||
#include "state/commands.hpp"
|
|
||||||
|
|
||||||
#include "util.hpp"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
Game::Game()
|
|
||||||
{
|
|
||||||
// advance simulation with 100 Hz
|
|
||||||
m_time_step = 1.0 / 100.0;
|
|
||||||
m_time_for_next_step = 0.0;
|
|
||||||
|
|
||||||
m_state = new game::State();
|
|
||||||
m_state->init();
|
|
||||||
|
|
||||||
m_state->addPlayer(0);
|
|
||||||
m_state->addPlayer(1);
|
|
||||||
m_state->addPlayer(2);
|
|
||||||
m_state->addPlayer(3);
|
|
||||||
//m_state->addPlayer(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Game::cycle(float dt)
|
|
||||||
{
|
|
||||||
static float acc = 0.0;
|
|
||||||
acc += dt;
|
|
||||||
|
|
||||||
float spawnInterval = 0.1;
|
|
||||||
while(acc > spawnInterval) {
|
|
||||||
acc -= spawnInterval;
|
|
||||||
|
|
||||||
float a = 2.0 * M_PI * util::randf_0_1();
|
|
||||||
float speed = 0.002;
|
|
||||||
m_state->players[0]->addCommand(new game::ShootCommand(a, speed));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (dt >= 10.0) {
|
|
||||||
//std::cout<<"time to big: " << dt << std::endl;
|
|
||||||
dt = m_time_step;
|
|
||||||
}
|
|
||||||
|
|
||||||
//std::cout<<"adding dt: " << dt << std::endl;
|
|
||||||
m_time_for_next_step += dt;
|
|
||||||
|
|
||||||
int steps = 0;
|
|
||||||
while(m_time_for_next_step >= m_time_step) {
|
|
||||||
//std::cout<<"time now: " << m_time_for_next_step << std::endl;
|
|
||||||
m_time_for_next_step -= m_time_step;
|
|
||||||
|
|
||||||
m_state->advance(m_time_step);
|
|
||||||
steps++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
(void) dt;
|
|
||||||
|
|
||||||
m_state->advance(dt);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,21 +1,39 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "state/state.hpp"
|
//#include <iostream>
|
||||||
|
//#include <memory>
|
||||||
|
//#include <utility>
|
||||||
|
#include <asio.hpp>
|
||||||
|
|
||||||
class Server {
|
#include "session.hpp"
|
||||||
|
|
||||||
|
using asio::ip::tcp;
|
||||||
|
|
||||||
|
class Server
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Server();
|
Server(asio::io_service& io_service, short port)
|
||||||
|
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
|
||||||
// main method of the game. run this regulary
|
socket_(io_service)
|
||||||
// return false if want to exit.
|
{
|
||||||
// bool cycle(float dt);
|
do_accept();
|
||||||
|
}
|
||||||
// for rendering
|
|
||||||
// const game::State *state() const { return m_state; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
game::State *m_state;
|
void do_accept()
|
||||||
|
{
|
||||||
|
acceptor_.async_accept(socket_,
|
||||||
|
[this](std::error_code ec)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
std::make_shared<Session>(std::move(socket_))->start();
|
||||||
|
}
|
||||||
|
|
||||||
float m_time_for_next_step;
|
do_accept();
|
||||||
float m_time_step;
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp::acceptor acceptor_;
|
||||||
|
tcp::socket socket_;
|
||||||
};
|
};
|
||||||
|
|
63
game/session.hpp
Normal file
63
game/session.hpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <asio.hpp>
|
||||||
|
|
||||||
|
using asio::ip::tcp;
|
||||||
|
|
||||||
|
class Session
|
||||||
|
: public std::enable_shared_from_this<Session>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Session(tcp::socket socket)
|
||||||
|
: socket_(std::move(socket))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
auto self(shared_from_this());
|
||||||
|
char hello[] = "\nUse \"n name\" to change name, \"v velocity\" to change velocity, \"c\" to clear past shots or \"q\" to close the connection.\nEverything else is interpreted as a shooting angle.\n\n>";
|
||||||
|
asio::async_write(socket_, asio::buffer(hello, strlen(hello)),
|
||||||
|
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
do_read();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void do_read()
|
||||||
|
{
|
||||||
|
auto self(shared_from_this());
|
||||||
|
socket_.async_read_some(asio::buffer(data_, max_length),
|
||||||
|
[this, self](std::error_code ec, std::size_t length)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
do_write(length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_write(std::size_t length)
|
||||||
|
{
|
||||||
|
auto self(shared_from_this());
|
||||||
|
asio::async_write(socket_, asio::buffer(data_, length),
|
||||||
|
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
do_read();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp::socket socket_;
|
||||||
|
enum { max_length = 1024 };
|
||||||
|
char data_[max_length];
|
||||||
|
};
|
Loading…
Reference in a new issue