1 // Copyright 2014-2016 the openage authors. See copying.md for legal info. 2 3 #pragma once 4 5 #include <exception> 6 #include <memory> 7 8 #include "typed_job_state_base.h" 9 10 namespace openage { 11 namespace job { 12 13 class JobGroup; 14 class JobManager; 15 16 /** 17 * A job is a wrapper around a shared job state object and is returned by the 18 * job manager. It can be used to retrieve the current state of the job and its 19 * result. 20 * A job is a lightweight object which only contains a pointer to its internal 21 * shared state. Thus it can be copied around without worrying about 22 * performance. Further it is not necessary to create or pass pointers to job 23 * objects. 24 * 25 * @param T the job's result type 26 */ 27 template<class T> 28 class Job { 29 private: 30 /** A shared pointer to the job's shared state. */ 31 std::shared_ptr<TypedJobStateBase<T>> state; 32 33 public: 34 /** 35 * Creates an empty job object that is not bound to any state. Should only 36 * be used as dummy object. 37 */ 38 Job() = default; 39 40 /** 41 * Returns whether this job has finished. If this job wrapper has no 42 * assigned background job, true will be returned. 43 */ is_finished()44 bool is_finished() const { 45 if (this->state) { 46 return this->state->finished.load(); 47 } 48 return true; 49 } 50 51 /** 52 * Returns this job's result if the background execution was successful. If 53 * an exception has happened, it will be rethrown. This method must not be 54 * called, if the job's execution has not yet finished. 55 */ get_result()56 T get_result() { 57 ENSURE(this->state, "getting result of a destroyed or uninitialised job"); 58 ENSURE(this->state->finished.load(), "trying to report a result of an unfinished job"); 59 if (this->state->exception != nullptr) { 60 std::rethrow_exception(this->state->exception); 61 } else { 62 return std::move(this->state->result); 63 } 64 } 65 66 private: 67 /** 68 * Creates a job with the given shared state. This method may only be called 69 * by the job manager. 70 */ Job(std::shared_ptr<TypedJobStateBase<T>> state)71 Job(std::shared_ptr<TypedJobStateBase<T>> state) 72 : 73 state{state} { 74 } 75 76 /* 77 * Job manager and job group have to be friends of job in order to access the 78 * private constructor. 79 */ 80 friend class JobGroup; 81 friend class JobManager; 82 }; 83 84 } 85 } 86