#include <map>
#include <ContextTypes.h>
-#include "ContextPublisher.h"
namespace ctx {
+ class ContextPublisher;
+
class ContextManager {
public:
~ContextManager();
{
}
-void ContextPublisher::addObserver(IContextObserver* observer)
+void ContextPublisher::addObserver(IContextObserver* observer, void* userData)
{
if (__observers.empty()) {
read();
subscribe();
}
- __observers.push_back(observer);
+ __observers.emplace_back(observer, userData);
}
void ContextPublisher::removeObserver(IContextObserver* observer)
{
- __observers.remove(observer);
+ __observers.remove_if(
+ [&](const ObserverInfo& info)->bool {
+ return (info.observer == observer);
+ });
if (__observers.empty()) {
unsubscribe();
void ContextPublisher::notifyObservers()
{
- for (auto& observer : __observers) {
- observer->ready();
+ for (auto& info : __observers) {
+ info.observer->contextDataReady(this, info.data);
}
}
{
__data = Json::nullValue;
}
+
+ContextPublisher::ObserverInfo::ObserverInfo(IContextObserver* o, void* d) :
+ observer(o),
+ data(d)
+{
+}
public:
virtual ~ContextPublisher();
- void addObserver(IContextObserver* observer);
+ void addObserver(IContextObserver* observer, void* userData);
void removeObserver(IContextObserver* observer);
virtual const char* getUri() const = 0;
Json::Value __data;
private:
- std::list<IContextObserver*> __observers;
+ struct ObserverInfo {
+ IContextObserver* observer;
+ void* data;
+ ObserverInfo(IContextObserver* o, void* d);
+ };
+ std::list<ObserverInfo> __observers;
};
}
namespace ctx {
+ class ContextPublisher;
+
class IContextObserver {
public:
virtual ~IContextObserver() {}
- virtual void ready() = 0;
+ virtual void contextDataReady(ContextPublisher* pubs, void* userData) = 0;
};
}
#include <Conf.h>
#include <JobAction.h>
#include "ContextManager.h"
+#include "ContextPublisher.h"
#include "SchedTimer.h"
#include "OnDemandJobRunner.h"
#include "PeriodicJobRunner.h"
void JobRunner::setState(JobState* state)
{
+ bool success = false;
+
delete __state;
__state = state;
IF_FAIL_VOID(__state);
try {
- if (__state->execute())
+ if ((success = __state->execute()))
__state->setClient(__client);
} catch (const std::runtime_error& e) {
- _E("State transtion failed: %s", e.what());
+ _E("State transition failed: %s", e.what());
+ _I("Terminating Job-%d of '%s'", getJobId(), getOwner().c_str());
+ terminate();
+ }
+
+ if (!success) {
+ _E("State transition failed");
_I("Terminating Job-%d of '%s'", getJobId(), getOwner().c_str());
terminate();
}
#include <JobInfo.h>
#define _ENTER _I("ENTER: Job-%d of '%s'", getJobId(), getOwner().c_str())
-#define _EXIT _I("EXIT : Job-%d of '%s'", getJobId(), getOwner().c_str())
+#define _EXIT _D("EXIT : Job-%d of '%s'", getJobId(), getOwner().c_str())
namespace ctx {
* limitations under the License.
*/
+#include <JobContext.h>
+#include "ContextManager.h"
+#include "ContextPublisher.h"
+#include "ReqVerificationState.h"
#include "TriggerStandbyState.h"
using namespace ctx;
TriggerStandbyState::~TriggerStandbyState()
{
_EXIT;
+ __unsubscribe();
}
bool TriggerStandbyState::execute()
{
- //TODO: Subscribe the trigger contexts.
- // If a context expires, verify its attributes, and transit to ReqVerificationState.
+ return __subscribe();
+}
+
+void TriggerStandbyState::contextDataReady(ContextPublisher* pubs, void* userData)
+{
+ JobTrigger* trigger = static_cast<JobTrigger*>(userData);
+
+ if (*trigger <= pubs->getData())
+ transit(new ReqVerificationState(this));
+}
+
+bool TriggerStandbyState::__subscribe()
+{
+ auto& triggers = static_cast<OnDemandJobInfo*>(getJobInfo())->getTriggers();
+
+ for (auto& trg : triggers) {
+ ContextPublisher* pubs = ContextManager::getPublisher(trg->getUri(), getUid());
+ IF_FAIL_RETURN(pubs, false);
+
+ pubs->addObserver(this, trg);
+ __publishers.push_back(pubs);
+ }
+
return true;
}
+
+void TriggerStandbyState::__unsubscribe()
+{
+ for (auto& pubs : __publishers) {
+ pubs->removeObserver(this);
+ }
+
+ __publishers.clear();
+}
#ifndef __CONTEXT_JOB_SCHEDULER_TRIGGER_STANDBY_STATE_H__
#define __CONTEXT_JOB_SCHEDULER_TRIGGER_STANDBY_STATE_H__
+#include <vector>
#include <WakeLock.h>
+#include "IContextObserver.h"
#include "JobState.h"
namespace ctx {
- class TriggerStandbyState : public JobState {
+ class ContextPublisher;
+
+ class TriggerStandbyState : public JobState, public IContextObserver {
public:
TriggerStandbyState(JobRunner* runner);
~TriggerStandbyState();
bool execute();
+ void contextDataReady(ContextPublisher* pubs, void* userData);
+
+ private:
+ bool __subscribe();
+ void __unsubscribe();
+
+ std::vector<ContextPublisher*> __publishers;
};
}