The International Simutrans Forum

Development => Technical Documentation => Topic started by: hreintke on January 01, 2013, 06:08:14 PM

Title: Experimenting with remote access
Post by: hreintke on January 01, 2013, 06:08:14 PM
LS,

I am experimenting getting simutrans accessible and/or updatable by webbrowser.
First for this I took the mongoose package which provides http/webserver fuctionality and added mongoose.c to the simutans project.

Now updated simworld.h with the following :


class karte_t
{
public:

    struct mg_context *ctx;

  static void *karte_t::callback(enum mg_event event,
                      struct mg_connection *conn);




and then updated simworld.cc to use start the webserver and reply to requests.


  void *karte_t::callback(enum mg_event event,
                      struct mg_connection *conn) {
  const struct mg_request_info *request_info = mg_get_request_info(conn);
 
  if (event == MG_NEW_REQUEST) {
    char content[1024];
    int content_length = _snprintf(content, sizeof(content),
                                  "Hello from Simutrans! Remote port: %d ",
  request_info->remote_port);
    mg_printf(conn,
              "HTTP/1.1 200 OK\r\n"
              "Content-Type: text/plain\r\n"
              "Content-Length: %d\r\n"        // Always set Content-Length
              "\r\n"
              "%s",
              content_length, content);
    // Mark as processed
    return "";
  } else {
    return NULL;
  }
}


karte_t::karte_t() :
settings(umgebung_t::default_einstellungen),
convoi_array(0),
ausflugsziele(16),
stadt(0),
marker(0,0)
{
const char *options[] = {"listening_ports", "8080", NULL};
ctx = mg_start( &callback, NULL, options);

// length of day and other time stuff



Works like a charm. Starting simutrans and using a browser to access localhost:8080 gives the expected result.

But now on to delivering some simutrans content. For that I exptected to be able to access the karte_t data and functions in the callback function but no luck there. Cannot acccess the data themself and also not using the this to get to there.

using this.get_fab_list().getcount()
gives the error 'this' : can only be referenced inside non-static member functions

using get_fab_list().getcount()
gives the error 'karte_t::get_fab_list' : illegal call of non-static member function

One thing to mention too is that I do need to have the callback function static, otherwise the usage of this in the ctx = mg_start( &callback, NULL, options); will not work.

Any hints to do further trials appreciated.

Kind regards,

Herman
Title: Re: Experimenting with remote access
Post by: jamespetts on January 01, 2013, 06:13:01 PM
The difficulty, I think, is with the requirement to have your callback function static. All the actual game data in Simutrans (including everything in karte_t), other than the settings, are instantiated objects, which cannot be accessed from static methods. The world itself is a non-static object of the class karte_t. (In theory, it would be possible to have multiple worlds with the same Simutrans process, but the code is not set up to cope with that, and there would be little point).
Title: Re: Experimenting with remote access
Post by: Ters on January 01, 2013, 06:28:46 PM
Most callbacks take a context parameter where user data can be passed. The karte_t instance must be sent through that. This might mean that the callback must be reregistered when a new game is created/loaded.
Title: Re: Experimenting with remote access
Post by: hreintke on January 02, 2013, 01:27:29 PM
LS,

The solution is indeed to pass the karte_t instance when starting the webservice.


karte_t::karte_t() :
{
const char *options[] = {"listening_ports", "8080", NULL};
ctx = mg_start( &callback, this, options);


and retrieving this userdata in the callback function.


void *karte_t::callback(enum mg_event event,
                      struct mg_connection *conn) {
  const struct mg_request_info *request_info = mg_get_request_info(conn);
 
  karte_t *myworld = (karte_t*) request_info->user_data;



In that way I do have access to the "welt".

Now further exerimenting with retrieving data using the web.

Herman