Files
joey 893aebaaaa - Embed javascript bootstrap file into gserver build
- Changed sendtorc/sendtonc functions to print all arguments to the function
- Modified call signature of onActionServerSide - onActionServerSide(player: Player, params: String[]) {}
- Fixed GS2 triggeractions to serverside
- Slightly improved some runtime execution errors in NC-tab
- Exposed some common functionality into the global object, so you can call them directly without referencing the server object:
  - functions: findlevel, findnpc, findplayer, savelog, sendtorc, sendtonc
  - global variables: allplayers, timevar, timevar2
2022-08-07 02:27:28 -04:00

149 lines
3.5 KiB
C++

#pragma once
#ifndef SCRIPTEXECUTION_H
#define SCRIPTEXECUTION_H
#include <algorithm>
#include <chrono>
#include <vector>
#include "ScriptAction.h"
#include "ScriptUtils.h"
#include "CScriptEngine.h"
class ScriptExecutionContext
{
public:
ScriptExecutionContext(CScriptEngine *scriptEngine)
: _scriptEngine(scriptEngine) { }
~ScriptExecutionContext() { resetExecution(); }
bool hasActions() const;
std::pair<unsigned int, double> getExecutionData();
void addAction(ScriptAction& action);
void addAction(ScriptAction&& action);
void addExecutionSample(const ScriptTimeSample& sample);
void resetExecution();
bool runExecution();
private:
CScriptEngine *_scriptEngine;
std::vector<ScriptAction> _actions;
std::vector<ScriptTimeSample> _scriptTimeSamples;
};
inline bool ScriptExecutionContext::hasActions() const
{
return !_actions.empty();
}
inline void ScriptExecutionContext::addExecutionSample(const ScriptTimeSample& sample)
{
#ifndef NOSCRIPTPROFILING
_scriptTimeSamples.push_back(sample);
// Remove any script samples over a minute old
//if (_scriptTimeSamples.size() > 1024)
{
auto curSampleTime = sample.sample_time;
while (!_scriptTimeSamples.empty())
{
auto oldSample = _scriptTimeSamples.begin();
auto sample_diff = std::chrono::duration_cast<std::chrono::minutes>(curSampleTime - oldSample->sample_time);
if (sample_diff.count() < 1)
break;
_scriptTimeSamples.erase(oldSample);
}
}
#endif
}
inline std::pair<unsigned int, double> ScriptExecutionContext::getExecutionData()
{
double exectime = 0.0;
unsigned int calls = 0;
#ifndef NOSCRIPTPROFILING
auto time_now = std::chrono::high_resolution_clock::now();
for (auto it = _scriptTimeSamples.begin(); it != _scriptTimeSamples.end();)
{
auto sample_diff = std::chrono::duration_cast<std::chrono::minutes>(time_now - (*it).sample_time);
if (sample_diff.count() >= 1)
{
it = _scriptTimeSamples.erase(it);
continue;
}
exectime += (*it).sample;
calls++;
++it;
}
#endif
return { calls, exectime };
}
inline void ScriptExecutionContext::addAction(ScriptAction& action)
{
if (action.getFunction()) {
_actions.push_back(std::move(action));
}
}
inline void ScriptExecutionContext::addAction(ScriptAction&& action)
{
if (action.getFunction()) {
_actions.push_back(std::move(action));
}
}
inline void ScriptExecutionContext::resetExecution()
{
_actions.clear();
#ifndef NOSCRIPTPROFILING
//_scriptTimeSamples.clear();
#endif
}
inline bool ScriptExecutionContext::runExecution()
{
// Take ownership of the queued actions, and clear them incase any scripts add actions.
std::vector<ScriptAction> iterateActions = std::move(_actions);
_actions.clear();
// Send start timer to engine
auto currentTimer = std::chrono::high_resolution_clock::now();
_scriptEngine->StartScriptExecution(currentTimer);
// iterate over queued actions
SCRIPTENV_D("Running %zd actions:\n", iterateActions.size());
for (auto & action : iterateActions)
{
SCRIPTENV_D("Running action: %s\n", action.getAction().c_str());
auto res = action.Invoke();
if (!res) {
_scriptEngine->reportScriptException(_scriptEngine->getScriptError());
}
}
if (!_scriptEngine->StopScriptExecution())
{
// TODO(joey): Report to server? What should we do, hm.
printf("Oh no we were killed!!\n");
}
#ifndef NOSCRIPTPROFILING
auto endTimer = std::chrono::high_resolution_clock::now();
auto time_diff = std::chrono::duration<double>(endTimer - currentTimer);
addExecutionSample({ time_diff.count(), endTimer });
#endif
return hasActions();
}
#endif