#include "thread_pool.h"
#include <iostream>
#include <functional>
#include <thread>
using namespace std;
//a function which will be executed in sub thread.
bool someFuntion()
{
    //sleep for a while
    this_thread::sleep_for(chrono::milliseconds(rand()%100+100));
    cout <<this_thread::get_id()<<":someFuntion()"<< endl;
    return true;
}

//a class has a method, which will be called in a thread different from the main thread.
class someClass
{
private:
    int m_n;
public:
    someClass(int n):m_n(n){}
    ~someClass(){}
public:
    bool foo (int k)
    {
        //sleep for a while
        this_thread::sleep_for(chrono::milliseconds(rand()%100+100));
        cout <<this_thread::get_id()<<":someClass::foo("<<k<<"), m_n = "<<m_n<<endl;
        m_n++;
        return (m_n<10?false:true);
    }
};

//let's test the thread.
int main()
{
    my_threadpool::thread_pool thread(4);
    cout <<"Being..."<<endl;
    for (int i=0;i<5;++i)
    {
        someClass object(i);
        //append object method with copy-constructor(value-assignment)
        thread.append(bind(&someClass::foo,object,i+1));
        //append a simple function task
        thread.append(&someFuntion);
        //append lamda
        thread.append(
                    [=]()->bool
        {
            this_thread::sleep_for(chrono::milliseconds(rand()%100+100));
            cout <<this_thread::get_id()<<":lamda"<<endl;
            return true;
        }
        );

    }

    //wait for all tasks done.
    thread.wait_for_idle();

    cout <<"Finished."<<endl;
    cout <<"Begin."<<endl;
    someClass object(0);
    for (int i=0;i<5;++i)
    {
        //append object method with reference
        thread.append(bind(&someClass::foo,&object,10));
        //append a simple function task
        thread.append(&someFuntion);
        //append lamda
        thread.append(
                    [=]()->bool
        {
            this_thread::sleep_for(chrono::milliseconds(rand()%100+100));
            cout <<this_thread::get_id()<<":lamda"<<endl;
            return true;
        }
        );

    }
    //wait for all tasks done.
    thread.wait_for_idle();

    cout <<"Finished."<<endl;
    //kill
    thread.terminate();
    //wait for killed
    thread.join();


    cout <<"Quit."<<endl;
}
