Blame view

ios/Runner/Wowgame/Classes/Parsing/ScenarioParsing/RepeatedActionScheduler.cpp 5.72 KB
cb213901   xiaoyu   添加一个游戏的源码和编译选项
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
  //
  //  RepeatedActionScheduler.cpp
  //  SteveMaggieCpp
  //
  //  Created by Katarzyna Kalinowska-Górska on 27.05.2017.
  //
  //
  
  #include <stdio.h>
  #include "RepeatedActionScheduler.h"
  #include "ActionParser.h"
  #include "JSONParseUtils.h"
  #include "MiscUtils.h"
  #include "ValueStorage.h"
  
  void RepeatedActionScheduler::clearAllScheduledActions(ActionParseDelegate* parseDelegate)
  {
      for(auto pair : _scheduledActionsData){
          parseDelegate->unschedule(pair.second.callbackKey);
          ValueStorage::getInstance().removeStoredValue(pair.second.storedValueKey, parseDelegate->getValueStorageContainerName());
      }
      
      _scheduledActionsData.clear();
      _waitingFunctions.clear();
  }
  
  //todo write all the stuff we can put to the repeated saction e.g. stpCondition (??)
  cocos2d::Action* RepeatedActionScheduler::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 = ValueStorage::getInstance().storeValue(jsonActionObject, parseDelegate->getValueStorageContainerName());
          
              auto repeatedFunction = [&](float dt, std::string pStoredValueKey, ActionParseDelegate* pParseDelegate, bool pNotifyDelegate){
                  
                  auto& actionParser = ActionParser::getInstance();
                  auto storedJsonActionObject = ValueStorage::getInstance().getStoredValue(pStoredValueKey, pParseDelegate->getValueStorageContainerName());
                  
                  std::string stopCondition;
                  if(JSONParseUtils::hasMemberBool(*storedJsonActionObject, "stopCondition")){
                      stopCondition = MiscUtils::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);
                      ValueStorage::getInstance().removeStoredValue(pStoredValueKey, pParseDelegate->getValueStorageContainerName());
                  
                  } 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 ActionParser::getInstance().embedFunctionInAction(std::bind(actionFunction, storedValueKey, actionTag, parseDelegate), jsonActionObject, parseDelegate, notifyDelegateWhenFinished);
              
          }
      }
      
      return NULL;
  }
  
  bool RepeatedActionScheduler::isActionValidRepeatedAction(const rapidjson::Value& jsonActionObject)
  { //todo maybe introduce such method to all parsed actions
      return JSONParseUtils::checkMemberBool(jsonActionObject, "repeat", true) && JSONParseUtils::hasMemberFloat(jsonActionObject, "repeatIntervalSeconds") && JSONParseUtils::hasMemberString(jsonActionObject, "repeatActionTag");
  }