Add a "SafeUDPpacket" and "SafeUDPpacketV" class.
I'm trying to merge UDPpacketVBuffer and SafeUDPpacketV. Seems pretty messy so far... hopefully this is fruitful.
This commit is contained in:
parent
dcbd011582
commit
60e282929f
11
Makefile
11
Makefile
@ -1,4 +1,4 @@
|
||||
.PHONY: all clean
|
||||
.PHONY: all clean reallyclean test
|
||||
.POSIX:
|
||||
|
||||
# {{{ Flags
|
||||
@ -27,6 +27,7 @@ OBJS := $(patsubst %,$(OBJDIR)/%.o,$(basename $(SRCS)))
|
||||
DEPS := $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))
|
||||
|
||||
COMMON_OBJS := \
|
||||
$(OBJDIR)/src/lib_GetOpt.o \
|
||||
$(OBJDIR)/src/lib_lua_common.o \
|
||||
$(OBJDIR)/src/lib_SDL_common.o \
|
||||
$(OBJDIR)/src/lib_SDL_Log.o \
|
||||
@ -186,9 +187,13 @@ $(OBJDIR)/%.o: %.cxx $(DEPDIR)/%.d
|
||||
$(COMPILE.cc) $<
|
||||
$(POSTCOMPILE)
|
||||
|
||||
clean: REALLYCLEAN?=@echo
|
||||
clean:
|
||||
@echo $(RM) $(DEPDIR) $(OBJDIR) $(PROGS)
|
||||
@echo $(RM) $(TEST_PROGS)
|
||||
$(REALLYCLEAN) $(RM) $(DEPDIR) $(OBJDIR) $(PROGS)
|
||||
$(REALLYCLEAN) $(RM) $(TEST_PROGS)
|
||||
|
||||
reallyclean:
|
||||
$(MAKE) REALLYCLEAN= clean
|
||||
|
||||
.PRECIOUS: $(DEPDIR)/%.d
|
||||
$(DEPDIR)/%.d: ;
|
||||
|
99
include/SafeUDPpacket.h
Normal file
99
include/SafeUDPpacket.h
Normal file
@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SDL_assert.h>
|
||||
#include <SDL_net.h>
|
||||
|
||||
class SafeUDPpacket
|
||||
{
|
||||
struct SDLNet_PacketDeleter
|
||||
{
|
||||
void operator () (UDPpacket* p)
|
||||
{
|
||||
SDLNet_FreePacket (p);
|
||||
p = NULL;
|
||||
}
|
||||
};
|
||||
std::unique_ptr<UDPpacket, SDLNet_PacketDeleter> m_packet;
|
||||
void Reset (UDPpacket* p)
|
||||
{
|
||||
m_packet.reset (p);
|
||||
}
|
||||
public:
|
||||
SafeUDPpacket (int size)
|
||||
{
|
||||
UDPpacket* p;
|
||||
if (NULL == (p = SDLNet_AllocPacket (size)))
|
||||
{
|
||||
throw "SDLNet_AllocPacket: " + std::string (SDLNet_GetError ());
|
||||
}
|
||||
Reset (p);
|
||||
}
|
||||
SafeUDPpacket (UDPpacket* p)
|
||||
{
|
||||
Reset (p);
|
||||
}
|
||||
UDPpacket* get (void) const
|
||||
{
|
||||
return m_packet.get ();
|
||||
}
|
||||
|
||||
int channel (int channel) const { return get()->channel = channel; }
|
||||
int channel (void) const { return get()->channel; }
|
||||
|
||||
int len (int len) const { return get()->len = len; }
|
||||
int len (void) const { return get()->len; }
|
||||
|
||||
int maxlen (int maxlen) const { return get()->maxlen = maxlen; }
|
||||
int maxlen (void) const { return get()->maxlen; }
|
||||
|
||||
int status (int status) const { return get()->status = status; }
|
||||
int status (void) const { return get()->status; }
|
||||
|
||||
IPaddress address (IPaddress address) const { return get()->address = address; }
|
||||
IPaddress address (void) const { return get()->address; }
|
||||
|
||||
Uint8 *data (Uint8* data) const { return get()->data = data; }
|
||||
Uint8 *data (void) const { return get()->data; }
|
||||
};
|
||||
|
||||
class SafeUDPpacketV
|
||||
{
|
||||
std::vector<SafeUDPpacket> m_packetV;
|
||||
public:
|
||||
SafeUDPpacketV (const void*, const int, const int mtu = 1450);
|
||||
SafeUDPpacketV (int howmany, int size)
|
||||
{
|
||||
UDPpacket** p;
|
||||
m_packetV.reserve (howmany);
|
||||
if (NULL == (p = SDLNet_AllocPacketV (howmany, size)))
|
||||
{
|
||||
throw "SDLNet_AllocPacketV: " + std::string (SDLNet_GetError ());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; (p != NULL) && (*p != NULL); p++)
|
||||
{
|
||||
m_packetV.push_back (SafeUDPpacket (*p));
|
||||
}
|
||||
SDL_assert ((m_packetV.size () > 0) && (howmany == (int)m_packetV.size ()));
|
||||
/*
|
||||
* SDLNet_FreePacketV just calls SDLNet_FreePacket on each packet.
|
||||
* The "packetV" itself is just something allocated on the heap.
|
||||
* We don't need this any longer.
|
||||
*/
|
||||
SDL_free (p);
|
||||
}
|
||||
}
|
||||
const SafeUDPpacket& get (size_t idx)
|
||||
{
|
||||
return m_packetV.at (idx);
|
||||
}
|
||||
size_t size (void) const
|
||||
{
|
||||
return m_packetV.size ();
|
||||
}
|
||||
std::string toString (void);
|
||||
};
|
@ -6,6 +6,9 @@
|
||||
#include "lib_lua_common.h"
|
||||
#include "UDPbase.h"
|
||||
|
||||
/*
|
||||
* Used as mFetchPacketsCallbackTimerID timeout
|
||||
*/
|
||||
#define DEFAULT_SOCKET_TIMEOUT 10
|
||||
|
||||
class Server : public UDPbase
|
||||
|
@ -5,32 +5,53 @@
|
||||
|
||||
#include <SDL_net.h>
|
||||
|
||||
#define DEFAULT_MAX_PACKET_SIZE 250
|
||||
#define DEFAULT_MAX_PACKET_SIZE 512
|
||||
|
||||
class UDPbase
|
||||
class
|
||||
UDPbase
|
||||
{
|
||||
int mChannel;
|
||||
IPaddress mIPAddress;
|
||||
void
|
||||
CloseAllSockets (void);
|
||||
|
||||
protected:
|
||||
std::vector<UDPsocket> UDPsocks;
|
||||
public:
|
||||
UDPbase (const char* host, const Uint16 port);
|
||||
UDPbase (const char* host, const Uint16 port, const int channel);
|
||||
UDPbase (const char *host, const Uint16 port);
|
||||
UDPbase (const char *host, const Uint16 port, const int channel);
|
||||
~UDPbase (void);
|
||||
|
||||
int ResolveHost (IPaddress*, const char*, const Uint16);
|
||||
int
|
||||
ResolveHost (IPaddress *, const char *, const Uint16);
|
||||
|
||||
UDPsocket UDP_Open (void);
|
||||
UDPsocket UDP_Open (const Uint16 port);
|
||||
void UDP_Close (UDPsocket sock);
|
||||
int UDP_Bind (UDPsocket sock, const int channel);
|
||||
void UDP_Unbind (UDPsocket sock, const int channel);
|
||||
IPaddress* UDP_GetPeerAddress (UDPsocket sock, const int channel);
|
||||
UDPsocket
|
||||
UDP_Open (void);
|
||||
UDPsocket
|
||||
UDP_Open (const Uint16 port);
|
||||
void
|
||||
UDP_Close (UDPsocket sock);
|
||||
int
|
||||
UDP_Bind (UDPsocket sock, const int channel);
|
||||
void
|
||||
UDP_Unbind (UDPsocket sock, const int channel);
|
||||
IPaddress *
|
||||
UDP_GetPeerAddress (UDPsocket sock, const int channel);
|
||||
|
||||
void CloseAllSockets (void);
|
||||
int
|
||||
getChannel (void) const
|
||||
{
|
||||
return
|
||||
mChannel;
|
||||
}
|
||||
UDPsocket
|
||||
getSocket (const size_t idx) const
|
||||
{
|
||||
return
|
||||
UDPsocks.
|
||||
at (idx);
|
||||
}
|
||||
|
||||
int getChannel (void) const { return mChannel; }
|
||||
UDPsocket getSocket (const size_t idx) const { return UDPsocks.at (idx); }
|
||||
|
||||
std::string toString (void);
|
||||
std::string
|
||||
toString (void);
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <SDL_net.h>
|
||||
|
||||
/**
|
||||
@ -36,25 +37,26 @@ Then free the leftover setup packet:
|
||||
*/
|
||||
class UDPpacketVBuffer
|
||||
{
|
||||
int npackets;
|
||||
UDPpacket** packetV;
|
||||
int m_howmany;
|
||||
UDPpacket** m_packetV;
|
||||
public:
|
||||
UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_t size);
|
||||
~UDPpacketVBuffer (void)
|
||||
{
|
||||
if (packetV)
|
||||
if (m_packetV)
|
||||
{
|
||||
SDLNet_FreePacketV (packetV);
|
||||
packetV = NULL;
|
||||
SDLNet_FreePacketV (m_packetV);
|
||||
m_packetV = NULL;
|
||||
}
|
||||
}
|
||||
int Send (UDPsocket sock)
|
||||
{
|
||||
int numsent = 0;
|
||||
if (packetV)
|
||||
if ((NULL != m_packetV) && (m_howmany > 0))
|
||||
{
|
||||
numsent = SDLNet_UDP_SendV (sock, packetV, npackets);
|
||||
numsent = SDLNet_UDP_SendV (sock, m_packetV, m_howmany);
|
||||
}
|
||||
return numsent;
|
||||
}
|
||||
std::string Reassemble (void);
|
||||
};
|
||||
|
11
include/lib_GetOpt.h
Normal file
11
include/lib_GetOpt.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
struct Init_CommonOpts
|
||||
{
|
||||
const char* host;
|
||||
int channel;
|
||||
int mtu;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
void common_GetOpt (int, char**, Init_CommonOpts*);
|
@ -26,15 +26,16 @@ bool command_Echo (const std::string& args)
|
||||
|
||||
bool command_Shell (const std::string& args)
|
||||
{
|
||||
int rc;
|
||||
if (args.empty ())
|
||||
char output[8192];
|
||||
FILE *fp;
|
||||
if (!args.empty ())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
c = system (args.c_str ());
|
||||
switch (rc)
|
||||
if ((fp = popen (args.c_str (), "r")))
|
||||
{
|
||||
while (fgets (output, (sizeof output) - 1, fp) != NULL) {
|
||||
printf ("%s", output);
|
||||
}
|
||||
pclose (fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
76
src/SafeUDPpacket.cpp
Normal file
76
src/SafeUDPpacket.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "SafeUDPpacket.h"
|
||||
|
||||
SafeUDPpacketV::SafeUDPpacketV (const void* buf, const int size, const int mtu)
|
||||
{
|
||||
int howmany, i, len, numsent;
|
||||
const uint8_t* bufPtr;
|
||||
const uint8_t* bufPtrEnd;
|
||||
|
||||
SDL_assert (NULL != buf);
|
||||
|
||||
SDL_assert (mtu > 0);
|
||||
howmany = (int) ceil ((double) size / (double) mtu);
|
||||
|
||||
i = 0;
|
||||
numsent = 0;
|
||||
bufPtr = (const uint8_t*) buf;
|
||||
bufPtrEnd = bufPtr + size;
|
||||
while ((i < howmany) && (bufPtr < bufPtrEnd) && (numsent < size))
|
||||
{
|
||||
SafeUDPpacket p (mtu);
|
||||
|
||||
len = size - numsent;
|
||||
if (len > mtu)
|
||||
len = mtu;
|
||||
/* Use SDLNet_UDP_Send to send an empty packet instead... it's probably simpler than all this machinery. */
|
||||
if (len < 1)
|
||||
break;
|
||||
|
||||
SDL_memset (p.data (), 0, mtu);
|
||||
p.len (len);
|
||||
p.maxlen (size);
|
||||
|
||||
/* But only memcpy in the relevant bits */
|
||||
SDL_memcpy (p.data (), bufPtr, len);
|
||||
m_packetV.push_back (std::move (p));
|
||||
|
||||
/* But we will want the destination address of this packet */
|
||||
/* Advance */
|
||||
bufPtr += len;
|
||||
numsent += len;
|
||||
i++;
|
||||
}
|
||||
|
||||
SDL_assert (howmany == (int)m_packetV.size ());
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
SafeUDPpacketV::toString (void)
|
||||
{
|
||||
int howmany, maxlen, mtu, numrecv;
|
||||
char* bufPtr;
|
||||
char* bufPtrEnd;
|
||||
std::string buf;
|
||||
|
||||
howmany = m_packetV.size ();
|
||||
SDL_assert (howmany > 0);
|
||||
|
||||
maxlen = m_packetV[0].maxlen ();
|
||||
SDL_assert (maxlen > 0);
|
||||
buf.reserve (maxlen);
|
||||
bufPtr = &buf[0];
|
||||
bufPtrEnd = bufPtr + maxlen;
|
||||
|
||||
for (numrecv = 0; (numrecv < howmany) && (bufPtr < bufPtrEnd); numrecv++)
|
||||
{
|
||||
mtu = m_packetV[numrecv].len ();
|
||||
SDL_assert (mtu > 0);
|
||||
memcpy (bufPtr, m_packetV[numrecv].data (), mtu);
|
||||
bufPtr += mtu;
|
||||
}
|
||||
|
||||
SDL_assert (numrecv == howmany);
|
||||
|
||||
return buf;
|
||||
}
|
@ -55,12 +55,17 @@ Server::AllocateApproximateResources (const int nclients)
|
||||
/*
|
||||
* If each client sends 1024 250 byte packets, that's 1/4th of a MB or 256000 bytes ...
|
||||
* seems fine for now as an upper limit.
|
||||
*
|
||||
* Since writing that comment, DEFAULT_MAX_PACKET_RECV_SIZE seems to have become 1024.
|
||||
* So, if 1024 clients are sending 1024 byte packets, we'll need 1 MB of memory.
|
||||
*
|
||||
* If 512 clients sending 512 byte packets, that's still 256000 bytes.
|
||||
*/
|
||||
if (packetV)
|
||||
{
|
||||
SDLNet_FreePacketV (packetV);
|
||||
}
|
||||
if (!(packetV = SDLNet_AllocPacketV (1024 * nclients, DEFAULT_MAX_PACKET_RECV_SIZE)))
|
||||
if (!(packetV = SDLNet_AllocPacketV (2 * nclients, DEFAULT_MAX_PACKET_RECV_SIZE)))
|
||||
{
|
||||
SDL_Log ("SDLNet_AllocPacketV: %s", SDLNet_GetError ());
|
||||
return -1;
|
||||
@ -215,6 +220,12 @@ Uint32 Server::FetchPacketsCallback (Uint32 interval, void *param)
|
||||
* TODO fix this wait timeout blocking issue
|
||||
*
|
||||
* I want this to block, but also to be stoppable.
|
||||
*
|
||||
* Maybe I can have clients send a disconnect packet, then when the queue is zero, stop this thread?
|
||||
*
|
||||
* How would clients send a connect packet? I'd have to listen indefinitely and that would block.
|
||||
*
|
||||
* Tricky tricky!
|
||||
*/
|
||||
numready = SDLNet_CheckSockets (server->getSocketSet (), (1000 * DEFAULT_SOCKET_TIMEOUT / 3) / 1000);
|
||||
if (numready < 0)
|
||||
|
@ -13,10 +13,10 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
|
||||
|
||||
mtu = src->len;
|
||||
SDL_assert (mtu > 0);
|
||||
npackets = (int) ceil ((double) size / (double) mtu);
|
||||
// SDL_Log ("%d", npackets);
|
||||
m_howmany = (int) ceil ((double) size / (double) mtu);
|
||||
// SDL_Log ("%d", m_howmany);
|
||||
|
||||
if (NULL == (packetV = SDLNet_AllocPacketV (npackets, mtu)))
|
||||
if (NULL == (m_packetV = SDLNet_AllocPacketV (m_howmany, mtu)))
|
||||
{
|
||||
throw "SDLNet_AllocPacketV: " + std::string (SDLNet_GetError ());
|
||||
}
|
||||
@ -25,7 +25,7 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
|
||||
nsent = size;
|
||||
bufPtr = (const uint8_t*) buf;
|
||||
bufPtrEnd = bufPtr + size;
|
||||
while ((i < npackets) && (bufPtr < bufPtrEnd) && (nsent > 0))
|
||||
while ((i < m_howmany) && (bufPtr < bufPtrEnd) && (nsent > 0))
|
||||
{
|
||||
len = nsent;
|
||||
if (len > mtu)
|
||||
@ -37,20 +37,51 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
|
||||
/* SDLNet_UDP_Send sets the channel in the argument,
|
||||
* this one takes it implicitly from the source UDPpacket.
|
||||
* Set it for all packets in the vector. */
|
||||
packetV[i]->channel = src->channel;
|
||||
m_packetV[i]->channel = src->channel;
|
||||
/* Always zero out the entire data */
|
||||
SDL_memset (packetV[i]->data, 0, mtu);
|
||||
SDL_memset (m_packetV[i]->data, 0, mtu);
|
||||
/* But only memcpy in the relevant bits */
|
||||
SDL_memcpy (packetV[i]->data, bufPtr, len);
|
||||
packetV[i]->len = len;
|
||||
SDL_memcpy (m_packetV[i]->data, bufPtr, len);
|
||||
m_packetV[i]->len = len;
|
||||
/* probably don't need maxlen or status set after this */
|
||||
packetV[i]->maxlen = size;
|
||||
packetV[i]->status = 0;
|
||||
m_packetV[i]->maxlen = size;
|
||||
m_packetV[i]->status = 0;
|
||||
/* But we will want the destination address of this packet */
|
||||
packetV[i]->address = src->address;
|
||||
m_packetV[i]->address = src->address;
|
||||
/* Advance */
|
||||
bufPtr += len;
|
||||
nsent -= len;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
UDPpacketVBuffer::Reassemble (void)
|
||||
{
|
||||
int i, maxlen, mtu, numrecv;
|
||||
char* bufPtr;
|
||||
char* bufPtrEnd;
|
||||
std::string buf;
|
||||
|
||||
SDL_assert (NULL != m_packetV);
|
||||
SDL_assert (NULL != m_packetV[0]);
|
||||
|
||||
maxlen = m_packetV[0]->maxlen;
|
||||
SDL_assert (maxlen > 0);
|
||||
buf.reserve (maxlen);
|
||||
bufPtr = &buf[0];
|
||||
bufPtrEnd = bufPtr + maxlen;
|
||||
|
||||
for (numrecv = 0; (numrecv < m_howmany) && m_packetV[numrecv] && (bufPtr < bufPtrEnd); numrecv++)
|
||||
{
|
||||
mtu = m_packetV[numrecv]->len;
|
||||
SDL_assert (mtu > 0);
|
||||
memcpy (bufPtr, m_packetV[numrecv]->data, mtu);
|
||||
bufPtr += mtu;
|
||||
}
|
||||
|
||||
SDL_assert (numrecv == m_howmany);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "UDPbase.h"
|
||||
#include "UDPpacketVBuffer.h"
|
||||
#include "events_common.h"
|
||||
#include "lib_GetOpt.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@ -33,11 +34,9 @@ static bool my_Input (SDL_Event*);
|
||||
static bool my_SDL_UserEvent (SDL_Event*);
|
||||
static bool my_SDL_WindowEvent (SDL_Event*);
|
||||
|
||||
static void my_GetOpt (int, char**);
|
||||
static void my_Init (int, char**);
|
||||
static void my_Render (void);
|
||||
static void my_UpdateValues (void);
|
||||
static void my_Usage (const char*);
|
||||
|
||||
struct Uniform_Values
|
||||
{
|
||||
@ -56,16 +55,19 @@ struct Uniform_Values
|
||||
|
||||
struct Client_State
|
||||
{
|
||||
Init_CommonOpts init_opts;
|
||||
|
||||
const char* host;
|
||||
int channel;
|
||||
int mtu;
|
||||
Uint16 port;
|
||||
|
||||
bool done;
|
||||
|
||||
Uint64 start, end;
|
||||
double diff;
|
||||
|
||||
UDPsocket udpsock;
|
||||
const char* host;
|
||||
Uint16 port;
|
||||
int channel;
|
||||
int mtu;
|
||||
|
||||
SDL_GLContext GLContext;
|
||||
SDL_Window* Window;
|
||||
@ -86,7 +88,6 @@ struct Client_State
|
||||
static std::unique_ptr<Cube> cube;
|
||||
static std::unique_ptr<Quad> quad;
|
||||
static std::unique_ptr<ShaderProgram> shader;
|
||||
static std::unique_ptr<UDPbase> client;
|
||||
|
||||
static Camera camera;
|
||||
static struct Client_State state;
|
||||
@ -95,87 +96,94 @@ static struct Uniform_Values values;
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
glm::mat4 model, view, projection;
|
||||
SDL_Event event;
|
||||
|
||||
my_Init (argc, argv);
|
||||
|
||||
shader = std::make_unique<ShaderProgram> ("./glsl/camera.v.glsl", "", "./glsl/new.f.glsl");
|
||||
if (!shader->ID)
|
||||
{
|
||||
SDL_Log ("Unable to load shader.");
|
||||
goto _out;
|
||||
}
|
||||
glm::mat4 model, view, projection;
|
||||
SDL_Event event;
|
||||
std::unique_ptr<UDPbase> client;
|
||||
|
||||
camera = Camera ();
|
||||
values.iResolution.x = state.Window_Width;
|
||||
values.iResolution.y = state.Window_Height;
|
||||
values.iResolution.z = 1.0;
|
||||
my_Init (argc, argv);
|
||||
|
||||
cube = std::make_unique<Cube> (1);
|
||||
quad = std::make_unique<Quad> (1);
|
||||
|
||||
state.mtu = 1450;
|
||||
state.done = false;
|
||||
client = std::make_unique<UDPbase> (state.host, state.port, state.channel);
|
||||
if (NULL == (state.udpsock = client->getSocket (0)))
|
||||
{
|
||||
SDL_Log ("Unable to open client port");
|
||||
goto _out;
|
||||
}
|
||||
if (-1 == (state.channel = client->getChannel ()))
|
||||
{
|
||||
SDL_Log ("Unable to bind client port");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
while (!state.done)
|
||||
{
|
||||
state.end = SDL_GetPerformanceCounter ();
|
||||
state.diff = Perf_Diff (state.start, state.end);
|
||||
while (state.diff < MIN_FRAME_MS)
|
||||
shader = std::make_unique<ShaderProgram> ("./glsl/camera.v.glsl", "", "./glsl/new.f.glsl");
|
||||
if (!shader->ID)
|
||||
{
|
||||
SDL_Log ("Unable to load shader.");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
camera = Camera ();
|
||||
values.iResolution.x = state.Window_Width;
|
||||
values.iResolution.y = state.Window_Height;
|
||||
values.iResolution.z = 1.0;
|
||||
|
||||
cube = std::make_unique<Cube> (1);
|
||||
quad = std::make_unique<Quad> (1);
|
||||
|
||||
state.done = false;
|
||||
|
||||
/* XXX is this okay? We are using C++ after all.. inheritance time */
|
||||
state.mtu = state.init_opts.mtu;
|
||||
state.host = state.init_opts.host;
|
||||
state.channel = state.init_opts.channel;
|
||||
state.port = state.init_opts.port;
|
||||
client = std::make_unique<UDPbase> (state.host, state.port, state.channel);
|
||||
if (NULL == (state.udpsock = client->getSocket (0)))
|
||||
{
|
||||
SDL_Log ("Unable to open client port");
|
||||
goto _out;
|
||||
}
|
||||
if (-1 == (state.channel = client->getChannel ()))
|
||||
{
|
||||
SDL_Log ("Unable to bind client port");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
while (!state.done)
|
||||
{
|
||||
SDL_Delay (1);
|
||||
state.end = SDL_GetPerformanceCounter ();
|
||||
state.diff = Perf_Diff (state.start, state.end);
|
||||
while (state.diff < MIN_FRAME_MS)
|
||||
{
|
||||
SDL_Delay (1);
|
||||
state.end = SDL_GetPerformanceCounter ();
|
||||
state.diff = Perf_Diff (state.start, state.end);
|
||||
}
|
||||
state.start = SDL_GetPerformanceCounter ();
|
||||
|
||||
SDL_SetRelativeMouseMode ((SDL_bool) state.InputRelativeMouseMode);
|
||||
SDL_CaptureMouse ((SDL_bool) state.InputCaptureMouse);
|
||||
|
||||
while (!state.done && SDL_PollEvent (&event))
|
||||
{
|
||||
state.done = my_Input (&event);
|
||||
}
|
||||
my_AnalogInput ();
|
||||
|
||||
projection = glm::perspective (glm::radians (camera.Zoom), (float) values.iResolution.x / (float) values.iResolution.y, camera.zNear, camera.zFar);
|
||||
view = camera.GetViewMatrix ();
|
||||
model = glm::mat4 (1.0f);
|
||||
|
||||
my_UpdateValues ();
|
||||
|
||||
shader->Use ();
|
||||
shader->Mat4 ("Projection", projection);
|
||||
shader->Mat4 ("View", view);
|
||||
shader->Mat4 ("Model", model);
|
||||
|
||||
my_Render ();
|
||||
|
||||
model = glm::mat4 (1.0f);
|
||||
model = glm::scale (model, glm::vec3 (10.0f));
|
||||
shader->Use ();
|
||||
shader->Mat4 ("Projection", projection);
|
||||
shader->Mat4 ("View", view);
|
||||
shader->Mat4 ("Model", model);
|
||||
cube->Draw ();
|
||||
|
||||
SDL_GL_SwapWindow (state.Window);
|
||||
}
|
||||
state.start = SDL_GetPerformanceCounter ();
|
||||
|
||||
SDL_SetRelativeMouseMode ((SDL_bool) state.InputRelativeMouseMode);
|
||||
SDL_CaptureMouse ((SDL_bool) state.InputCaptureMouse);
|
||||
|
||||
while (!state.done && SDL_PollEvent (&event))
|
||||
{
|
||||
state.done = my_Input (&event);
|
||||
}
|
||||
my_AnalogInput ();
|
||||
|
||||
projection = glm::perspective (glm::radians (camera.Zoom), (float) values.iResolution.x / (float) values.iResolution.y, camera.zNear, camera.zFar);
|
||||
view = camera.GetViewMatrix ();
|
||||
model = glm::mat4 (1.0f);
|
||||
|
||||
my_UpdateValues ();
|
||||
|
||||
shader->Use ();
|
||||
shader->Mat4 ("Projection", projection);
|
||||
shader->Mat4 ("View", view);
|
||||
shader->Mat4 ("Model", model);
|
||||
|
||||
my_Render ();
|
||||
|
||||
model = glm::mat4 (1.0f);
|
||||
model = glm::scale (model, glm::vec3 (10.0f));
|
||||
shader->Use ();
|
||||
shader->Mat4 ("Projection", projection);
|
||||
shader->Mat4 ("View", view);
|
||||
shader->Mat4 ("Model", model);
|
||||
cube->Draw ();
|
||||
|
||||
SDL_GL_SwapWindow (state.Window);
|
||||
}
|
||||
|
||||
_out:
|
||||
client->CloseAllSockets ();
|
||||
SDL_GL_DeleteContext (state.GLContext);
|
||||
SDL_DestroyWindow (state.Window);
|
||||
common_SDL_Quit ();
|
||||
@ -188,7 +196,8 @@ static void
|
||||
my_Init (int argc, char** argv)
|
||||
{
|
||||
common_Signal_Init ();
|
||||
my_GetOpt (argc, argv);
|
||||
|
||||
common_GetOpt (argc, argv, &state.init_opts);
|
||||
|
||||
state.start = state.end = SDL_GetPerformanceCounter ();
|
||||
|
||||
@ -314,7 +323,7 @@ my_Input (SDL_Event* event)
|
||||
case SHADER_PROGRAM_REFRESH:
|
||||
my_SDL_UserEvent (event);
|
||||
break;
|
||||
break;
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
my_SDL_WindowEvent (event);
|
||||
break;
|
||||
@ -467,7 +476,8 @@ my_SDL_UserEvent (SDL_Event* event)
|
||||
SDL_Log ("SHADER_PROGRAM_REFRESH");
|
||||
/* Actually do the refresh */
|
||||
GLuint id;
|
||||
try {
|
||||
try
|
||||
{
|
||||
id = shader->Compile3ShaderBuffers (shader->getVertexPath (), shader->getGeometryPath (), shader->getFragmentPath ());
|
||||
}
|
||||
catch (const std::string& e)
|
||||
@ -510,37 +520,3 @@ my_SDL_WindowEvent (SDL_Event* event)
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Usage (const char* argv0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-h] [-s host] [-p port]\n", argv0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_GetOpt (int argc, char** argv)
|
||||
{
|
||||
int opt;
|
||||
state.host = "localhost";
|
||||
state.port = 6666;
|
||||
state.channel = -1;
|
||||
while ((opt = getopt (argc, argv, "hp:s:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'p':
|
||||
state.port = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
state.host = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
my_Usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
43
src/lib_GetOpt.cpp
Normal file
43
src/lib_GetOpt.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "lib_GetOpt.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void
|
||||
common_Usage (const char* argv0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-h] [-s server] [-p port]\n", argv0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_GetOpt (int argc, char** argv, Init_CommonOpts* state)
|
||||
{
|
||||
int opt;
|
||||
state->host = "localhost";
|
||||
state->channel = -1;
|
||||
state->mtu = 1450;
|
||||
state->port = 6666;
|
||||
while ((opt = getopt (argc, argv, "hm:p:s:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'm':
|
||||
state->mtu = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 'p':
|
||||
state->port = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
state->host = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
common_Usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "util.h"
|
||||
#include "Server.h"
|
||||
#include "Commands.h"
|
||||
#include "lib_GetOpt.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@ -21,16 +22,16 @@
|
||||
#include <getopt.h> /* getopt */
|
||||
|
||||
static bool done = false;
|
||||
static const char* host = NULL;
|
||||
static Uint16 port = 6666;
|
||||
static const char* prompt_str = "> ";
|
||||
|
||||
/* XXX gross */
|
||||
static std::vector<char> server_data;
|
||||
static bool left_shift = false;
|
||||
|
||||
static std::unique_ptr<Server> server;
|
||||
|
||||
static bool my_SDL_UserEvent (SDL_Event *);
|
||||
static int my_StdinThread(void*);
|
||||
static void my_Usage (const char *);
|
||||
static void my_GetOpt (int, char **);
|
||||
static void my_ProcessPacket (UDPpacket *);
|
||||
static bool my_StdinThread_Helper (const std::string&);
|
||||
static void my_ShowPrompt (void);
|
||||
@ -38,13 +39,14 @@ static void my_ShowPrompt (void);
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
Init_CommonOpts init_opts;
|
||||
SDL_Event ev;
|
||||
|
||||
my_GetOpt (argc, argv);
|
||||
common_GetOpt (argc, argv, &init_opts);
|
||||
common_Signal_Init ();
|
||||
common_SDL_Init ();
|
||||
|
||||
server = std::make_unique<Server> (host, port);
|
||||
server = std::make_unique<Server> (init_opts.host, init_opts.port);
|
||||
|
||||
if (server->Start () < 0)
|
||||
{
|
||||
@ -116,10 +118,6 @@ my_SDL_UserEvent (SDL_Event * ev)
|
||||
|
||||
|
||||
/* XXX gross */
|
||||
static std::vector<char> server_data;
|
||||
static bool left_shift = false;
|
||||
|
||||
/* XXX gross */
|
||||
static void
|
||||
my_ProcessPacket (UDPpacket* packet)
|
||||
{
|
||||
@ -237,37 +235,6 @@ my_ProcessPacket (UDPpacket* packet)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Usage (const char *argv0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-h] [-s server] [-p port]\n", argv0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_GetOpt (int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
while ((opt = getopt (argc, argv, "hp:s:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'p':
|
||||
port = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
host = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
my_Usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void my_ShowPrompt (void)
|
||||
{
|
||||
printf ("\n%s", prompt_str);
|
||||
|
11
test/test_SafeUDPpacket.cpp
Normal file
11
test/test_SafeUDPpacket.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "SafeUDPpacket.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int size;
|
||||
size = 1;
|
||||
UDPpacket* p_ptr;
|
||||
SafeUDPpacket p (size);
|
||||
p_ptr = p.get ();
|
||||
return 0;
|
||||
}
|
@ -40,54 +40,54 @@ static std::unique_ptr<UDPbase> client;
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
UDPsocket udpsock;
|
||||
|
||||
common_Signal_Init ();
|
||||
my_GetOpt (argc, argv);
|
||||
|
||||
common_SDL_Init ();
|
||||
|
||||
client = std::make_unique<UDPbase> (host, port);
|
||||
if (NULL == (udpsock = client->UDP_Open (0)))
|
||||
{
|
||||
SDL_Log ("Unable to open client port");
|
||||
return -1;
|
||||
}
|
||||
if (-1 == (channel = client->UDP_Bind (udpsock, -1)))
|
||||
{
|
||||
SDL_Log ("Unable to bind client port");
|
||||
return -1;
|
||||
}
|
||||
UDPsocket udpsock;
|
||||
|
||||
std::string buf;
|
||||
if (path == "-")
|
||||
{
|
||||
try {
|
||||
std::string line;
|
||||
while (getline (std::cin, line))
|
||||
{
|
||||
buf += line + "\n";
|
||||
common_Signal_Init ();
|
||||
my_GetOpt (argc, argv);
|
||||
|
||||
common_SDL_Init ();
|
||||
|
||||
client = std::make_unique<UDPbase> (host, port);
|
||||
if (NULL == (udpsock = client->UDP_Open (0)))
|
||||
{
|
||||
SDL_Log ("Unable to open client port");
|
||||
return -1;
|
||||
}
|
||||
if (-1 == (channel = client->UDP_Bind (udpsock, -1)))
|
||||
{
|
||||
SDL_Log ("Unable to bind client port");
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string buf;
|
||||
if (path == "-")
|
||||
{
|
||||
try {
|
||||
std::string line;
|
||||
while (getline (std::cin, line))
|
||||
{
|
||||
buf += line + "\n";
|
||||
}
|
||||
}
|
||||
catch (std::ifstream::failure& e) {
|
||||
// std::cout << e << std::endl;
|
||||
}
|
||||
}
|
||||
catch (std::ifstream::failure& e) {
|
||||
// std::cout << e << std::endl;
|
||||
else
|
||||
{
|
||||
FileIO f (path, "r");
|
||||
buf = f.ReadToString ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FileIO f (path, "r");
|
||||
buf = f.ReadToString ();
|
||||
}
|
||||
|
||||
UDPpacket* packet = SDLNet_AllocPacket (buf.length ());
|
||||
IPaddress* addr = SDLNet_UDP_GetPeerAddress (udpsock, channel);
|
||||
packet->len = DEFAULT_MAX_PACKET_SIZE;
|
||||
packet->address = *addr;
|
||||
packet->channel = channel;
|
||||
UDPpacketVBuffer packetV (packet, &buf[0], buf.length ());
|
||||
packetV.Send (udpsock);
|
||||
|
||||
client->CloseAllSockets ();
|
||||
UDPpacket* packet = SDLNet_AllocPacket (buf.length ());
|
||||
IPaddress* addr = SDLNet_UDP_GetPeerAddress (udpsock, channel);
|
||||
packet->len = DEFAULT_MAX_PACKET_SIZE;
|
||||
packet->address = *addr;
|
||||
packet->channel = channel;
|
||||
UDPpacketVBuffer packetV (packet, &buf[0], buf.length ());
|
||||
packetV.Send (udpsock);
|
||||
}
|
||||
|
||||
common_SDL_Quit ();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user