Skip to content

Commit 53a89e0

Browse files
authored
Merge af28ee3 into 050a010
2 parents 050a010 + af28ee3 commit 53a89e0

File tree

6 files changed

+89
-66
lines changed

6 files changed

+89
-66
lines changed

src/modules/Bots/playerbot/strategy/Action.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ namespace ai
112112
class ActionBasket
113113
{
114114
public:
115-
ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event) :
115+
ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, const Event& event) :
116116
action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event) {}
117117
virtual ~ActionBasket(void) {}
118118
public:
119119
float getRelevance() {return relevance;}
120120
ActionNode* getAction() {return action;}
121-
Event getEvent() { return event; }
121+
const Event& getEvent() { return event; }
122122
bool isSkipPrerequisites() { return skipPrerequisites; }
123123
void AmendRelevance(float k) {relevance *= k; }
124124
void setRelevance(float relevance) { this->relevance = relevance; }

src/modules/Bots/playerbot/strategy/Engine.cpp

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ Engine::Engine(PlayerbotAI* ai, AiObjectContext *factory) : PlayerbotAIAware(ai)
1212
{
1313
lastRelevance = 0.0f;
1414
testMode = false;
15+
strategiesDirty = false;
1516
}
1617

1718
// Executes actions before the main action
18-
bool ActionExecutionListeners::Before(Action* action, Event event)
19+
bool ActionExecutionListeners::Before(Action* action, const Event& event)
1920
{
2021
bool result = true;
2122
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
@@ -26,7 +27,7 @@ bool ActionExecutionListeners::Before(Action* action, Event event)
2627
}
2728

2829
// Executes actions after the main action
29-
void ActionExecutionListeners::After(Action* action, bool executed, Event event)
30+
void ActionExecutionListeners::After(Action* action, bool executed, const Event& event)
3031
{
3132
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
3233
{
@@ -35,7 +36,7 @@ void ActionExecutionListeners::After(Action* action, bool executed, Event event)
3536
}
3637

3738
// Overrides the result of the action execution
38-
bool ActionExecutionListeners::OverrideResult(Action* action, bool executed, Event event)
39+
bool ActionExecutionListeners::OverrideResult(Action* action, bool executed, const Event& event)
3940
{
4041
bool result = executed;
4142
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
@@ -46,7 +47,7 @@ bool ActionExecutionListeners::OverrideResult(Action* action, bool executed, Eve
4647
}
4748

4849
// Checks if the action execution is allowed
49-
bool ActionExecutionListeners::AllowExecution(Action* action, Event event)
50+
bool ActionExecutionListeners::AllowExecution(Action* action, const Event& event)
5051
{
5152
bool result = true;
5253
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
@@ -71,6 +72,16 @@ Engine::~Engine(void)
7172
{
7273
Reset();
7374
strategies.clear();
75+
ClearActionNodeCache();
76+
}
77+
78+
void Engine::ClearActionNodeCache()
79+
{
80+
for (unordered_map<string, ActionNode*>::iterator i = actionNodeCache.begin(); i != actionNodeCache.end(); i++)
81+
{
82+
delete i->second;
83+
}
84+
actionNodeCache.clear();
7485
}
7586

7687
// Resets the engine by clearing the action queue, triggers, and multipliers
@@ -79,8 +90,7 @@ void Engine::Reset()
7990
ActionNode* action = NULL;
8091
do
8192
{
82-
action = queue.Pop();
83-
delete action;
93+
action = queue.Pop(); // popped from queue, remain in cache
8494
} while (action != NULL);
8595

8696
for (list<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
@@ -98,10 +108,18 @@ void Engine::Reset()
98108
multipliers.clear();
99109
}
100110

101-
// Initializes the engine by resetting it and initializing strategies
111+
// Marks the engine for reinitialization at the next DoNextAction entry
102112
void Engine::Init()
113+
{
114+
strategiesDirty = true;
115+
}
116+
117+
// Initializes strategies, triggers, multipliers, and default actions
118+
void Engine::InitStrategies()
103119
{
104120
Reset();
121+
ClearActionNodeCache();
122+
strategiesDirty = false;
105123

106124
for (map<string, Strategy*>::iterator i = strategies.begin(); i != strategies.end(); i++)
107125
{
@@ -132,6 +150,11 @@ bool Engine::DoNextAction(Unit* unit, int depth)
132150
bool actionExecuted = false;
133151
ActionBasket* basket = NULL;
134152

153+
if (strategiesDirty)
154+
{
155+
InitStrategies();
156+
}
157+
135158
time_t currentTime = time(0);
136159
aiObjectContext->Update();
137160
ProcessTriggers();
@@ -188,7 +211,6 @@ bool Engine::DoNextAction(Unit* unit, int depth)
188211
LogAction("A:%s - OK", action->getName().c_str());
189212
MultiplyAndPush(actionNode->getContinuers(), 0, false, event);
190213
lastRelevance = relevance;
191-
delete actionNode;
192214
break;
193215
}
194216
else
@@ -208,7 +230,6 @@ bool Engine::DoNextAction(Unit* unit, int depth)
208230
lastRelevance = relevance;
209231
LogAction("A:%s - USELESS", action->getName().c_str());
210232
}
211-
delete actionNode;
212233
}
213234
}
214235
while (basket);
@@ -240,23 +261,30 @@ bool Engine::DoNextAction(Unit* unit, int depth)
240261
// Creates an action node based on the action name
241262
ActionNode* Engine::CreateActionNode(string name)
242263
{
264+
unordered_map<string, ActionNode*>::iterator cached = actionNodeCache.find(name);
265+
if (cached != actionNodeCache.end())
266+
{
267+
return cached->second;
268+
}
269+
270+
ActionNode* node = NULL;
243271
for (map<string, Strategy*>::iterator i = strategies.begin(); i != strategies.end(); i++)
244272
{
245-
Strategy* strategy = i->second;
246-
ActionNode* node = strategy->GetAction(name);
273+
node = i->second->GetAction(name);
247274
if (node)
248-
{
249-
return node;
250-
}
275+
break;
276+
}
277+
if (!node)
278+
{
279+
node = new ActionNode(name, /*P*/ NULL, /*A*/ NULL, /*C*/ NULL);
251280
}
252-
return new ActionNode (name,
253-
/*P*/ NULL,
254-
/*A*/ NULL,
255-
/*C*/ NULL);
281+
282+
actionNodeCache[name] = node;
283+
return node;
256284
}
257285

258286
// Multiplies the relevance of actions and pushes them to the queue
259-
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event)
287+
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, const Event& event)
260288
{
261289
bool pushed = false;
262290
if (actions)
@@ -281,11 +309,6 @@ bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool sk
281309
queue.Push(new ActionBasket(action, k, skipPrerequisites, event));
282310
pushed = true;
283311
}
284-
else
285-
{
286-
delete action;
287-
}
288-
289312
delete nextAction;
290313
}
291314
else
@@ -317,21 +340,18 @@ ActionResult Engine::ExecuteAction(string &name)
317340

318341
if (!action->isPossible())
319342
{
320-
delete actionNode;
321343
return ACTION_RESULT_IMPOSSIBLE;
322344
}
323345

324346
if (!action->isUseful())
325347
{
326-
delete actionNode;
327348
return ACTION_RESULT_USELESS;
328349
}
329350

330351
action->MakeVerbose();
331352
Event emptyEvent;
332353
result = ListenAndExecute(action, emptyEvent);
333354
MultiplyAndPush(action->getContinuers(), 0.0f, false, emptyEvent);
334-
delete actionNode;
335355
return result ? ACTION_RESULT_OK : ACTION_RESULT_FAILED;
336356
}
337357

@@ -487,13 +507,12 @@ string Engine::ListStrategies()
487507
}
488508

489509
// Pushes an action node to the queue again
490-
void Engine::PushAgain(ActionNode* actionNode, float relevance, Event event)
510+
void Engine::PushAgain(ActionNode* actionNode, float relevance, const Event& event)
491511
{
492512
NextAction** nextAction = new NextAction*[2];
493513
nextAction[0] = new NextAction(actionNode->getName(), relevance);
494514
nextAction[1] = NULL;
495515
MultiplyAndPush(nextAction, relevance, true, event);
496-
delete actionNode;
497516
}
498517

499518
// Checks if the engine contains a specific strategy type
@@ -523,7 +542,7 @@ Action* Engine::InitializeAction(ActionNode* actionNode)
523542
}
524543

525544
// Listens and executes an action
526-
bool Engine::ListenAndExecute(Action* action, Event event)
545+
bool Engine::ListenAndExecute(Action* action, const Event& event)
527546
{
528547
bool actionExecuted = false;
529548

src/modules/Bots/playerbot/strategy/Engine.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <unordered_map>
34
#include "Action.h"
45
#include "Queue.h"
56
#include "Trigger.h"
@@ -16,10 +17,10 @@ namespace ai
1617
{
1718
public:
1819
virtual ~ActionExecutionListener() = default; // Add a virtual destructor
19-
virtual bool Before(Action* action, Event event) = 0;
20-
virtual bool AllowExecution(Action* action, Event event) = 0;
21-
virtual void After(Action* action, bool executed, Event event) = 0;
22-
virtual bool OverrideResult(Action* action, bool executed, Event event) = 0;
20+
virtual bool Before(Action* action, const Event& event) = 0;
21+
virtual bool AllowExecution(Action* action, const Event& event) = 0;
22+
virtual void After(Action* action, bool executed, const Event& event) = 0;
23+
virtual bool OverrideResult(Action* action, bool executed, const Event& event) = 0;
2324
};
2425

2526
// -----------------------------------------------------------------------------------------------------------------------
@@ -34,10 +35,10 @@ namespace ai
3435

3536
// ActionExecutionListener
3637
public:
37-
virtual bool Before(Action* action, Event event);
38-
virtual bool AllowExecution(Action* action, Event event);
39-
virtual void After(Action* action, bool executed, Event event);
40-
virtual bool OverrideResult(Action* action, bool executed, Event event);
38+
virtual bool Before(Action* action, const Event& event);
39+
virtual bool AllowExecution(Action* action, const Event& event);
40+
virtual void After(Action* action, bool executed, const Event& event);
41+
virtual bool OverrideResult(Action* action, bool executed, const Event& event);
4142

4243
public:
4344
/**
@@ -127,14 +128,16 @@ namespace ai
127128
virtual ~Engine(void);
128129

129130
private:
130-
bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event);
131+
bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, const Event& event);
131132
void Reset();
132133
void ProcessTriggers();
133134
void PushDefaultActions();
134-
void PushAgain(ActionNode* actionNode, float relevance, Event event);
135+
void PushAgain(ActionNode* actionNode, float relevance, const Event& event);
135136
ActionNode* CreateActionNode(string name);
136137
Action* InitializeAction(ActionNode* actionNode);
137-
bool ListenAndExecute(Action* action, Event event);
138+
bool ListenAndExecute(Action* action, const Event& event);
139+
void ClearActionNodeCache();
140+
void InitStrategies();
138141

139142
private:
140143
void LogAction(const char* format, ...);
@@ -146,8 +149,10 @@ namespace ai
146149
std::list<Multiplier*> multipliers; /**< List of multipliers */
147150
AiObjectContext* aiObjectContext; /**< AI object context */
148151
std::map<string, Strategy*> strategies; /**< Map of strategies */
152+
std::unordered_map<string, ActionNode*> actionNodeCache; /**< Cache of action nodes by name */
149153
float lastRelevance; /**< Last relevance value */
150154
std::string lastAction; /**< Last executed action */
155+
bool strategiesDirty; /**< True when strategies changed and ActualInit() is pending */
151156

152157
public:
153158
bool testMode; /**< Flag for test mode */

src/modules/Bots/playerbot/strategy/Event.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ namespace ai
6262
*
6363
* @return string The source of the event
6464
*/
65-
string getSource() { return source; }
65+
const string& getSource() { return source; }
6666

6767
/**
6868
* @brief Get the parameter of the event
6969
*
7070
* @return string The parameter of the event
7171
*/
72-
string getParam() { return param; }
72+
const string& getParam() { return param; }
7373

7474
/**
7575
* @brief Get the packet associated with the event

0 commit comments

Comments
 (0)