abigagli / TaskScheduler

Use functors, lambdas and std::chrono to schedule tasks in the near future

Home Page:http://naios.github.io/TaskScheduler

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

C++11 Task Scheduler

Build Status Coverity Scan Build Status

Preview

Use std::chrono::duration to schedule functional types (std::function, std::bind, lambdas and functors) in the near future. Easy and safe to use and dependency free. Offers the possibility to reschedule, repeat, manipulate and cancel tasks.


Table of Contents

Usage Instructions

Schedulig tasks

Scheduling a task is very easy, just declare a TaskScheduler and use TaskScheduler::Schedule.

#include <iostream>
#include <chrono>
#include "TaskScheduler.hpp"

using namespace tsc;

TaskScheduler scheduler;

scheduler.Schedule(std::chrono::seconds(10), [](TaskContext context)
{
    std::cout << "This is executed once." << std::endl;
});

Duration literals and typedefs

If your compiler and projects supports C++14 use std::duration_literals for better readability like:

using namespace std::literals;

scheduler.Schedule(10s, ...);

Using C++11 you can also define std::chrono::duration shorthand typedefs for easier usage:

typedef std::chrono::milliseconds Milliseconds;
typedef std::chrono::seconds Seconds;
typedef std::chrono::minutes Minutes;
typedef std::chrono::hours Hours;

scheduler.Schedule(Seconds(10), ...);

Updating the Scheduler

In most cases you will use an application-/ gameloop which is called in a constant interval, otherwise you need to create a thread to do so:

// An update loop where diff is in milliseconds
void Update(unsigned int diff)
{
    scheduler.Update(std::chrono::milliseconds(diff));
}

// An update loop where diff is in seconds
void Update(std::chrono::seconds& diff)
{
    scheduler.Update(diff);
}

// An update loop where no diff time is given
void Update()
{
    scheduler.Update();
}

Reapeat Tasks

// Schedule a simple function that is executed every 10s
scheduler
	.Schedule(std::chrono::seconds(10), [](TaskContext context)
	{
	    std::cout << "This is executed once." << std::endl;
	})
	// Lazy overloading, just concat everything together...
	.Schedule(std::chrono::seconds(10), [](TaskContext context)
	{
	    std::cout << "This is executed every 10s..." << std::endl;

	    // Repeat this event.
	    context.Repeat();
	});

// Update the scheduler to now
scheduler.Update();

// ...or add a difftime, useful if you are using a global update tick.
scheduler.Update(std::chrono::milliseconds(200));

Groups

Since you can't compare std::functions to each other you can organize scheduled functions in groups to manage it.

enum ScheduledGroups
{
    GROUP_FIRST, // Group 0 is also a group ,-)
    GROUP_SECOND,
};

scheduler.Schedule(std::chrono::seconds(5), GROUP_FIRST, [](TaskContext context)
{
    std::cout << "You won't see me..." << std::endl;
});

// Cancel the group GROUP_FIRST
scheduler.CancelGroup(GROUP_FIRST);

// ... or cancel all goups.
scheduler.CancelAll();

Contexts

To access the TaskScheduler safely from within a scheduled function there is a TaskContext provided. It's important that you never pass the TaskScheduler as lambda capture! Use the TaskContext instead. The task context provides the ability to reschedule the executed function, cancel groups or schedule new tasks.

If you schedule new tasks from within a context the time is calculated from the context, it's possible that the function gets executed at the same update tick!

scheduler.Schedule(std::chrono::milliseconds(1500), [](TaskContext context)
{
    std::cout << "Message (1/3)" << std::endl;

    context
        .Schedule(std::chrono::milliseconds(800), [](TaskContext context)
        {
            std::cout << "Message (2/3)" << std::endl;
        })
        .Schedule(std::chrono::milliseconds(900), [](TaskContext context)
        {
            std::cout << "Message (3/3)" << std::endl;
            context->CancelAll();
        });
});

// Only 1 update is called and all 3 functions are executed.
scheduler.Update(std::chrono::seconds(60));

Coverage

Automatic unit tests are automatically executed through Travis CI to check the code integrity. See the tests for details.

Requirements

The TaskScheduler is dependency free and was tested with following c++11 capable compiler and confirmed to work:

  • Visual Studio 2013 Update 4
  • Visual Studio 2015
  • GNU GCC 4.8+
  • Clang 3.4+

License

The TaskScheduler is licensed under the Apache 2 License.

About

Use functors, lambdas and std::chrono to schedule tasks in the near future

http://naios.github.io/TaskScheduler

License:Apache License 2.0


Languages

Language:C++ 93.7%Language:CMake 6.3%