ToyRepeatedActionScheduler.cpp
5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//
// ToyRepeatedActionScheduler.cpp
// SteveMaggieCpp
//
// Created by Katarzyna Kalinowska-Górska on 27.05.2017.
//
//
#include <stdio.h>
#include "ToyRepeatedActionScheduler.h"
#include "ToyActionParser.h"
#include "ToyJSONParseUtils.h"
#include "ToyMiscUtils.h"
#include "ToyValueStorage.h"
void ToyRepeatedActionScheduler::clearAllScheduledActions(ActionParseDelegate* parseDelegate)
{
for(auto pair : _scheduledActionsData){
parseDelegate->unschedule(pair.second.callbackKey);
ToyValueStorage::getInstance().removeStoredValue(pair.second.storedValueKey, parseDelegate->getToyValueStorageContainerName());
}
_scheduledActionsData.clear();
_waitingFunctions.clear();
}
//todo write all the stuff we can put to the repeated saction e.g. stpCondition (??)
cocos2d::Action* ToyRepeatedActionScheduler::scheduleActionIfNeeded(const rapidjson::Value& jsonActionObject, ActionParseDelegate* parseDelegate, bool notifyDelegateWhenFinished){
// if given action is a repeated action and it is not already scheduled
if(this->isActionValidRepeatedAction(jsonActionObject)){
std::string actionTag = jsonActionObject["repeatActionTag"].GetString();
if(_scheduledActionsData.find(actionTag) == _scheduledActionsData.end()){
auto storedValueKey = ToyValueStorage::getInstance().storeValue(jsonActionObject, parseDelegate->getToyValueStorageContainerName());
auto repeatedFunction = [&](float dt, std::string pStoredValueKey, ActionParseDelegate* pParseDelegate, bool pNotifyDelegate){
auto& actionParser = ToyActionParser::getInstance();
auto storedJsonActionObject = ToyValueStorage::getInstance().getStoredValue(pStoredValueKey, pParseDelegate->getToyValueStorageContainerName());
std::string stopCondition;
if(ToyJSONParseUtils::hasMemberBool(*storedJsonActionObject, "stopCondition")){
stopCondition = ToyMiscUtils::boolToString((*storedJsonActionObject)["stopCondition"].GetBool());
} else {
stopCondition = (*storedJsonActionObject)["stopCondition"].GetString();
}
std::string repeatActionTag = (*storedJsonActionObject)["repeatActionTag"].GetString();
if(actionParser.checkCondition(stopCondition, pParseDelegate) == true){
pParseDelegate->unschedule(repeatActionTag);
_scheduledActionsData.erase(repeatActionTag);
ToyValueStorage::getInstance().removeStoredValue(pStoredValueKey, pParseDelegate->getToyValueStorageContainerName());
} else {
auto repeatIntervalSeconds = (*storedJsonActionObject)["repeatIntervalSeconds"].GetFloat();
auto repeatTimeSinceUserInteraction = (*storedJsonActionObject)["repeatTimeSinceUserInteraction"].GetFloat();
auto now = cocos2d::utils::getTimeInMilliseconds();
auto timeSinceLastRun = _scheduledActionsData[repeatActionTag].lastTimeRun == -1 ? repeatIntervalSeconds + 1 : (now - _scheduledActionsData[repeatActionTag].lastTimeRun)/1000;
auto lastTouchTime = pParseDelegate->getLastScreenTouchTime();
auto timeSinceLastUserTouch = lastTouchTime == -1 ? repeatIntervalSeconds + 1 : (now - lastTouchTime)/1000.0;
if(_scheduledActionsData.find(repeatActionTag) != _scheduledActionsData.end() && (timeSinceLastRun >= repeatIntervalSeconds && timeSinceLastUserTouch >= repeatTimeSinceUserInteraction)){
actionParser.parseAndRunAction(*storedJsonActionObject, pParseDelegate, pNotifyDelegate);
if(_scheduledActionsData.find(repeatActionTag) != _scheduledActionsData.end()){
_scheduledActionsData[repeatActionTag].lastTimeRun = now;
}
}
}
};
std::function<void(float)> boundRepeatedFunction = std::bind(repeatedFunction, std::placeholders::_1, storedValueKey, parseDelegate, notifyDelegateWhenFinished);
_waitingFunctions.insert({actionTag, boundRepeatedFunction});
auto actionFunction = [&](std::string pStoredValueKey, std::string pActionTag, ActionParseDelegate* pParseDelegate){
// log("scheduling repeated funciton");
ScheduledActionsData data;
data.lastTimeRun = -1;
data.callbackKey = pActionTag;
data.storedValueKey = pStoredValueKey;
_scheduledActionsData[pActionTag] = data;
if(_waitingFunctions.find(pActionTag) != _waitingFunctions.end()){
auto pRepeatedFunction = _waitingFunctions.at(pActionTag);
pParseDelegate->schedule(pRepeatedFunction, pActionTag, 1);
_waitingFunctions.erase(pActionTag);
}
};
return ToyActionParser::getInstance().embedFunctionInAction(std::bind(actionFunction, storedValueKey, actionTag, parseDelegate), jsonActionObject, parseDelegate, notifyDelegateWhenFinished);
}
}
return NULL;
}
bool ToyRepeatedActionScheduler::isActionValidRepeatedAction(const rapidjson::Value& jsonActionObject)
{ //todo maybe introduce such method to all parsed actions
return ToyJSONParseUtils::checkMemberBool(jsonActionObject, "repeat", true) && ToyJSONParseUtils::hasMemberFloat(jsonActionObject, "repeatIntervalSeconds") && ToyJSONParseUtils::hasMemberString(jsonActionObject, "repeatActionTag");
}