The online racing simulator
Control timing for RCMs
(13 posts, started )
Control timing for RCMs
Hi, I'm working in my insim example app which I built from scratch -using karl's C example as a base to get the socket and insim connection to work- and I've reached a point where I'd like to use/test RCM messages.

The "problem" is that I know how to send a RCM to any player, but I'm guessing that the correct way to clear those RCMs would be using an independent thread that would act as a timer that clears one specific RCM message, or maybe even handles all RCMs present at one time. Maybe I'm totally wrong and there's another way to do it. Of course I don't want my main thread to be on an active wait for like 4 or 5 seconds to clear the RCM and then continue.

I haven't used threads in a LONG time, and I think that I would breaking platform compatibility because I think there are no standard libraries for threads in C/C++. Right now all my code would be linux/windows compatible with tiny changes to the InSim API I've created, and I wouldn't like to break compatiblity...

Can anyone point me into the right direction?

PS: Please no responses like "use LFS External, that will do the job" or the like. I'm just toying with InSim to learn how it works, and as an exercise on C/C++ programming. I have no intention to pick any already existing InSim library.
pthreads has been ported to windows, which would allow you to make it still cross platform if you use those - http://sourceware.org/pthreads-win32/ (I've not really touched pthreads in my life, sadly).

There are a few other alternatives, one of which would be to use the APR (Apache Runtime) libraries, but that leads you down having to use something called "pools", which are a managed memory framework.

The other solution is to keep it all in the same process and place a timing check hook in somewhere around the insim packet parsing. It does that you can't guarantee the accuracy of the timing though, as I'm sure you're aware of...
OK. I have downloaded pthreads-w32 and I'll try those

Now I have another question related to RCMs. I've noticed that when I send a RCM to a user it will erase other RCMs like the ones that tell you about your lap and split times. My intention was to provide additional info on split times added to the standard RCMs. When I receive an IS_SPX packet the "split time xxx" appears for a fraction of a second and then it gets erased my my insim-created RCM. I'd like to know if any of these would be the solution:

- Somehow disable the standard RCM messages generated by LFS so the only ones that show are the ones my InSim app send.
- Use transparent buttons instead of RCMs and try to manually place them in the center if the screen below the standard generated RCMs.

EDIT: I already have a working example using Pthreads-w32, and it seems pretty fast. Now I need to add mutual exclusion checking and tidy up a little the code. I needed to make some basic structures global in order for the threads to be able to access some data, and that leads to mutex issues and blablabla... A pain, but thinking about it, it's the way it must be done (I think).
Or you could use an event based, timed system to clear them while in the main loop.
Quote from Dygear :Or you could use an event based, timed system to clear them while in the main loop.

Auto-quote myself:
Quote from MaKaKaZo :PS: Please no responses like "use LFS External, that will do the job" or the like. I'm just toying with InSim to learn how it works, and as an exercise on C/C++ programming. I have no intention to pick any already existing InSim library.

This also means that I don't have any intention to completely rewrite my API and all the code I've been doing. Most of all, I don't have experience with event based systems, so that would be a completely time consuming task to research. Maybe some day. Anyway, I don't think that event based, timed systems do any kind of magic. If you don't use threads for these kind of things I think any other solution would be slower.
Well don't go away that far from event handling.

POSIX compatible OS's implement signals for inter process communication, which you can see as some kind of low level events.

So if you're sending a RCM, you could use the alarm() function (defined in unistd.h) to deliver a timed SIGALARM signal to your own process.

You need to define a signal handler for the signal of course.

I have no idea if there are similar low level solutions for Microshit OS's.

If you got a stable INSIM implemention in C/C++, it would be very nice to release it to the community.
I am not a fan of C# and would really like to see a platform indepedent solution in C/C++, even if if not has all the functionalty of LFS_external.
Problem with C/C++ is, that standard libraries (or better lack of them) are useless piece of shit. Which means if you want to produce something as basic as dealing with threads, synchronization, timers, network communication, you need to use nonstandard cross platform libraries like boost, wxwidgets, sdl... Each of them have their weaknesses, but still better (faster) to try to use one of these than to implement your own compatibility layer...
Quote from yankman :
I am not a fan of C# and would really like to see a platform indepedent solution in C/C++, even if if not has all the functionalty of LFS_external.

C# is a nice modern language (and I tried a lot of them :nod. It just has some misplaced namespaces, some shitty libraries tied to Win crap OS, and I see no reason why there is no native compiler...

C++ is so unproductive that I haven't touched it for a long time. That (and upper post) probably explains why there is no insim helper library available for C/C++. I did plan to make one tho, but I got sick of Insim, and I am waiting for wxwidgets 3.0.
Don't mix things up here.
C# is a programming language as well as C++ but .NET is a lib or a framework of libs ... thats a big difference.

I know that you made lapper using C#.NET.
I modded it quite a while ago for the oval junkies.

Your are right about C++. Beside that I find the STL very useful, there is not much to make a complete software,
but it is not platform dependend.

.NET is a Microsoft development so it runs natively only on win32.
Mono is a try to get .NET to other OS' but it has a lot of drawbacks.

So there is no way for plattform indepency in case of network and graphics features.

Why are u trying wxwidgets ? Isn't it a library which uses the same api as win32 ? (analog to mono which implements the .NET api)

If I could choose I would use QT.
It is easy to program and better to understand than win32-API
.

Enough OT
Quote from yankman :Don't mix things up here.
C# is a programming language as well as C++ but .NET is a lib or a framework of libs ... thats a big difference.

I didn't mix anything. Just said that language without rich standardized libraries is PITA for productive cross platform development. Hmm, .net libraries afaik are not standardized, but at least mono covers most important classes.

Quote from yankman :
Your are right about C++. Beside that I find the STL very useful, there is not much to make a complete software,
but it is not platform dependend.

I have very bad experience with portability of STL. Even in wxwidgets they decided not to use it...

Quote from yankman :
Why are u trying wxwidgets ? Isn't it a library which uses the same api as win32 ? (analog to mono which implements the .NET api)

It's cross platform C++ OO library (abstraction layer to OS - minimal subset with optional superset ). Coding looks bit ugly (indeed classes look much like MFC), they stripped some C++ features like exceptions, namespaces, etc (cause they obviously are not supported by some compilers and/or are too differently implemented - precise standardization ftw :rolleyes

http://www.wxwidgets.org/

I don't like QT, since you lose native GUI and it has too restricted license.

And it's not OT, I suggested a library .
Don't fight guy s

Quote from yankman :If you got a stable INSIM implemention in C/C++, it would be very nice to release it to the community.
I am not a fan of C# and would really like to see a platform indepedent solution in C/C++, even if if not has all the functionalty of LFS_external.

Well, I'm a noob programmer and I don't think what I did could be of any use to the LFS programmers base, except for learning purposes.

What I've done is a simple class and a few independent functions that I use for my tests. I work with my little class and the original insim.h (InSim.txt in docs folders renamed to .h) which defines the C structs for all IS packets, enums, etc. Here is my CInsim.h file

#ifndef _CINSIM_H
#define _CINSIM_H

typedef unsigned char byte;
typedef unsigned short word;

// Custom InSim specific database types
typedef struct NodeLap NodeLap;
typedef struct CompCar CompCar;
typedef struct
{
int x;
int y;
int z;
} Vec;
typedef struct
{
float x;
float y;
float z;
} Vector;

#include "insim.h"
#include <winsock2.h>

#define PACKET_BUFFER_SIZE 512
#define PACKET_MAX_SIZE 512
#define IS_TIMEOUT 5

// Definition for our buffer datatype
struct buffer
{
char buffer[PACKET_BUFFER_SIZE]; // Packet buffer - 512 should be more than enough
unsigned int bytes; // Number of bytes currently in buffer
};

/**
* CInsim class to manage the Insim connection and processing of the packets
*/
class CInsim
{
private:
SOCKET sock; // Socket
struct buffer gbuf; // Our global buffer
struct buffer lbuf; // Our local buffer
char packet[PACKET_MAX_SIZE]; // A buffer where the current packet is stored
fd_set readfd, exceptfd; // File descriptor watches
struct timeval select_timeout; // timeval struct for the select() call

public:
CInsim::CInsim(); // Constructor
// "int init(...)" Establishes connection with the socket and insim.
//+ The last argument ch_ver is a pointer to a IS_VER struct. If it's used an IS_VER packet
//+ will be returned. If ch_ver is not used in the call no IS_VER will be requested/returned.
int init (int protocol, char *addr, word port, char *product, char *admin, byte prefix = 0, struct IS_VER *ch_ver = NULL);
int isclose(); // Closes connection from insim and from the socket
int next_packet(); // Gets next packet ready into "char packet[]"
char peek_packet(); // Returns the type of the current packet
void* get_packet(); // Returns a pointer to the current packet. Must be casted
int send_packet(void* packet); // Sends a packet to the host
};

/**
* Other functions!!!
*/

char* mstostr (long milisecs, char *str); // Converts miliseconds to a C string.

#endif

In my main I start the connection, send some initialization packets to setup the host, and then I enter the main loop in which I get the next packet. Then I have a switch inside that loop that calls individual functions depending on the packet received.

If someone finds this interesting I have no problem releasing it to the community. I think that all the code related to my CInsim class is in English.
The solution i allready have for this into DLFSS Project, can't be apply to your project and way.


But i think this code can maybe helpfull, for your threadind system.
http://zthread.sourceforge.net/ (Licence is compatible with GPL).

I worked with this code for 3 year on www.mangosproject.org (MMORPG Server), and i can say! Rock And Roll!

Working on: 32/64 Bits - MacOSX, Window and Linux, really hope it help you!
Quote from Greenseed :The solution i allready have for this into DLFSS Project, can't be apply to your project and way.


But i think this code can maybe helpfull, for your threadind system.
http://zthread.sourceforge.net/ (Licence is compatible with GPL).

I worked with this code for 3 year on www.mangosproject.org (MMORPG Server), and i can say! Rock And Roll!

Working on: 32/64 Bits - MacOSX, Window and Linux, really hope it help you!

Thanks for the info. I already have it working with Pthreads-w32 mentioned by Karl in the first reply. It's working nice but I don't like much that I need a dll for it to work. That's Windows for you

Control timing for RCMs
(13 posts, started )
FGED GREDG RDFGDR GSFDG