Showing posts with label game programming. Show all posts
Showing posts with label game programming. Show all posts

Friday, October 6, 2017

It's magic! std::bind

'std::bind' is a powerful helper for working around 'std::function'.

'std::bind' makes a instance of 'std::function' within user-defined parameter.

You don't need to consider how does 'std::bind' work, just learn how to use it.

Anyway, let's have a look at examples.

#include <iostream>
#include <functional>

std::function<void()> func;

void no_arg()
{
  std::cout << "no_arg\n";
}

void int_arg(int i)
{
  std::cout << "int_arg " << i << std::endl;
}

class Foo
{
  public:
  void no_arg_method() {
    std::cout << "no_arg_method\n";
  }
};

int main()
{
  // func and no_arg are both take no arguments, so we can assign no_arg to func directry
  func = &no_arg;
  func();
  
  // int_arg takes one int argument, so we need to use std::bind to make new function object
  // with int_arg taking one argument of 10.
  func = std::bind(&int_arg, 10);
  func(); // no arguments provided here.
  
  // Foo::no__arg_method takes no arguments, but it needs implicit argument of 'this',
  // std::bind can bind instance address like this.
  Foo foo;
  func = std::bind(&Foo::no_arg_method, &foo);
  func(); // calls foo's no_arg_method

}
repl.it

And here is one more example, with function object taking arguments.

#include <iostream>
#include <functional>

std::function<void(int i)> func;

void int_arg(int i)
{
  std::cout << "int_arg " << i << std::endl;
}

void int_arg2(int i, int j)
{
  std::cout << "int_arg2 " << i << "/" << j << std::endl;
}

class Foo
{
  public:
  void int_arg_method(int i) {
    std::cout << "int_arg_method " << i << std::endl;
  }
};

int main()
{
  // func and no_arg are both take one int argument, so we can assign int_arg to func directry
  func = &int_arg;
  func(20); // call with argument;
  
  // int_arg2 takes two int argument, so we need to use std::bind to make new function object
  // with int_arg2 taking one argument(10 for instance).
  // std::placeholders::_1 means that 'will be replaced by first argument by caller' 
  func = std::bind(&int_arg2, 10, std::placeholders::_1);
  func(20); // std::placeholders::_1 is replaced to 20
  
  // also we can use placeholders with class method.
  Foo foo;
  func = std::bind(&Foo::int_arg_method, &foo, std::placeholders::_1);
  func(20);

}
repl.it


Tuesday, September 5, 2017

Game loop and multi-threading in game programming

In most of games, the game status will change in every moment, even if there is no user input.

So game program must have game loop, which updates internal status time by time.

The game loop looks like this.

#include <chrono>
#include <thread>

using namespace std::chrono;

void game_loop()
{
    while(true)
    {
        steady_clock::time_point begin = steady_clock::now();

        input();            // receive and store user input.
        update();           // update game.
        draw_screen();      // draw.

        steady_clock::time_point end = steady_clock::now();

        constexpr fps = milliseconds(1000/60); // 60 frames per second
        milliseconds elapsed_time = duration_cast<milliseconds>(end - begin);

        if( fps > elapsed_time ) {
            std::this_thread::sleep_for( fps - elapsed_time ); // wait for next frame
        }
    }
}

Each loop is called 'frame'. In this example each frame is intended to be called 60 times per second.
If one frame takes more than 1/60 second, the game will get slower.

So, we have to take care not to take 1/60 second in one frame.

In game program, tipical long-time task is loading resource(3D models, texture, database, etc.).
If the program execute loading resource in 'update()', the game will stop at the frame.

Multi-threading is used to solve this kind of problem.
In 'update()', when the program desides to load some resource, create loading request to other thread.
The thread loads the resource, and send the data back to main thread.

The game loop will be going, even when loading resource.


It&#39;s magic! std::bind

'std::bind' is a powerful helper for working around 'std::function'. 'std::bind' makes a instance of 'std::fun...