mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-10 04:26:42 +03:00
Replace WarningsAsErrors usage with ScriptAssert usage.
For recoverable errors, add some recovery behaviour and logging so a level designer can see in the log what was done as a result of the error. Warn about default behaviour if no callbacks are added.
This commit is contained in:
parent
052b03ec96
commit
ead31e63f2
9 changed files with 36 additions and 61 deletions
|
@ -650,7 +650,7 @@ unsigned CALLBACK GameMain(void *)
|
||||||
// Initialise legacy memory buffer and game timer
|
// Initialise legacy memory buffer and game timer
|
||||||
init_game_malloc();
|
init_game_malloc();
|
||||||
TIME_Init();
|
TIME_Init();
|
||||||
if (g_GameFlow->IntroImagePath.empty() && WarningsAsErrors)
|
if (g_GameFlow->IntroImagePath.empty())
|
||||||
{
|
{
|
||||||
throw TENScriptException("Intro image path is not set.");
|
throw TENScriptException("Intro image path is not set.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "GameLogicScript.h"
|
#include "GameLogicScript.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
#include "box.h"
|
#include "box.h"
|
||||||
#include "lara.h"
|
#include "lara.h"
|
||||||
|
@ -28,7 +29,6 @@ functions and callbacks for game specific scripts
|
||||||
|
|
||||||
extern GameFlow* g_GameFlow;
|
extern GameFlow* g_GameFlow;
|
||||||
GameScript* g_GameScript;
|
GameScript* g_GameScript;
|
||||||
extern bool const WarningsAsErrors = true;
|
|
||||||
|
|
||||||
GameScript::GameScript(sol::state* lua) : LuaHandler{ lua }, m_itemsMapId{}, m_itemsMapName{}, m_meshesMapName{}
|
GameScript::GameScript(sol::state* lua) : LuaHandler{ lua }, m_itemsMapId{}, m_itemsMapName{}, m_meshesMapName{}
|
||||||
{
|
{
|
||||||
|
@ -621,8 +621,7 @@ void LuaVariables::SetVariable(std::string key, sol::object value)
|
||||||
variables[key] = value;
|
variables[key] = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (WarningsAsErrors)
|
ScriptAssert(false, "Variable " + key + " has an unsupported type.", ERROR_MODE::TERMINATE);
|
||||||
throw std::runtime_error("unsupported variable type");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,19 +630,19 @@ void GameScript::ExecuteFunction(std::string const & name)
|
||||||
{
|
{
|
||||||
sol::protected_function func = (*m_lua)[name.c_str()];
|
sol::protected_function func = (*m_lua)[name.c_str()];
|
||||||
auto r = func();
|
auto r = func();
|
||||||
if (WarningsAsErrors && !r.valid())
|
if (!r.valid())
|
||||||
{
|
{
|
||||||
sol::error err = r;
|
sol::error err = r;
|
||||||
throw TENScriptException(err.what());
|
ScriptAssert(false, err.what(), ERROR_MODE::TERMINATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doCallback(sol::protected_function const & func) {
|
static void doCallback(sol::protected_function const & func) {
|
||||||
auto r = func();
|
auto r = func();
|
||||||
if (WarningsAsErrors && !r.valid())
|
if (!r.valid())
|
||||||
{
|
{
|
||||||
sol::error err = r;
|
sol::error err = r;
|
||||||
throw TENScriptException(err.what());
|
ScriptAssert(false, err.what(), ERROR_MODE::TERMINATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,40 +654,38 @@ void GameScript::OnStart()
|
||||||
|
|
||||||
void GameScript::OnLoad()
|
void GameScript::OnLoad()
|
||||||
{
|
{
|
||||||
if (m_onLoad.valid())
|
if(m_onLoad.valid())
|
||||||
doCallback(m_onLoad);
|
doCallback(m_onLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameScript::OnControlPhase()
|
void GameScript::OnControlPhase()
|
||||||
{
|
{
|
||||||
if (m_onControlPhase.valid())
|
if(m_onControlPhase.valid())
|
||||||
doCallback(m_onControlPhase);
|
doCallback(m_onControlPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameScript::OnSave()
|
void GameScript::OnSave()
|
||||||
{
|
{
|
||||||
if (m_onSave.valid())
|
if(m_onSave.valid())
|
||||||
doCallback(m_onSave);
|
doCallback(m_onSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameScript::OnEnd()
|
void GameScript::OnEnd()
|
||||||
{
|
{
|
||||||
if (m_onEnd.valid())
|
if(m_onEnd.valid())
|
||||||
doCallback(m_onEnd);
|
doCallback(m_onEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameScript::InitCallbacks()
|
void GameScript::InitCallbacks()
|
||||||
{
|
{
|
||||||
auto assignCB = [this](sol::protected_function& func, char const* luaFunc) {
|
auto assignCB = [this](sol::protected_function& func, std::string const & luaFunc) {
|
||||||
func = (*m_lua)[luaFunc];
|
func = (*m_lua)[luaFunc];
|
||||||
if (WarningsAsErrors && !func.valid())
|
std::string err{ "Level's script does not define callback " + luaFunc};
|
||||||
{
|
if (!ScriptAssert(func.valid(), err)) {
|
||||||
std::string err{ "Level's script file requires callback \"" };
|
TENLog("Defaulting to no " + luaFunc + " behaviour.", LogLevel::Warning, LogConfig::All);
|
||||||
err += std::string{ luaFunc };
|
|
||||||
err += "\"";
|
|
||||||
throw TENScriptException(err);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
assignCB(m_onStart, "OnStart");
|
assignCB(m_onStart, "OnStart");
|
||||||
assignCB(m_onLoad, "OnLoad");
|
assignCB(m_onLoad, "OnLoad");
|
||||||
assignCB(m_onControlPhase, "OnControlPhase");
|
assignCB(m_onControlPhase, "OnControlPhase");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "GameScriptAIObject.h"
|
#include "GameScriptAIObject.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "GameScriptPosition.h"
|
#include "GameScriptPosition.h"
|
||||||
#include <sol.hpp>
|
#include <sol.hpp>
|
||||||
/***
|
/***
|
||||||
|
@ -10,7 +11,6 @@ AI object
|
||||||
@pragma nostrip
|
@pragma nostrip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
constexpr auto LUA_CLASS_NAME{ "AIObject" };
|
constexpr auto LUA_CLASS_NAME{ "AIObject" };
|
||||||
|
|
||||||
|
@ -105,8 +105,7 @@ std::string GameScriptAIObject::GetName() const
|
||||||
|
|
||||||
void GameScriptAIObject::SetName(std::string const & id)
|
void GameScriptAIObject::SetName(std::string const & id)
|
||||||
{
|
{
|
||||||
if (id.empty() && WarningsAsErrors)
|
ScriptAssert(!id.empty(), "Name cannot be blank", ERROR_MODE::TERMINATE);
|
||||||
throw TENScriptException("Name cannot be blank");
|
|
||||||
|
|
||||||
// remove the old name if we have one
|
// remove the old name if we have one
|
||||||
s_callbackRemoveName(m_aiObject.luaName);
|
s_callbackRemoveName(m_aiObject.luaName);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "GameScriptCameraInfo.h"
|
#include "GameScriptCameraInfo.h"
|
||||||
#include "GameScriptPosition.h"
|
#include "GameScriptPosition.h"
|
||||||
/***
|
/***
|
||||||
|
@ -8,8 +9,6 @@ Camera info
|
||||||
@pragma nostrip
|
@pragma nostrip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
static constexpr auto LUA_CLASS_NAME{ "CameraInfo" };
|
static constexpr auto LUA_CLASS_NAME{ "CameraInfo" };
|
||||||
|
|
||||||
static auto index_error = index_error_maker(GameScriptCameraInfo, LUA_CLASS_NAME);
|
static auto index_error = index_error_maker(GameScriptCameraInfo, LUA_CLASS_NAME);
|
||||||
|
@ -63,8 +62,7 @@ std::string GameScriptCameraInfo::GetName() const
|
||||||
|
|
||||||
void GameScriptCameraInfo::SetName(std::string const & id)
|
void GameScriptCameraInfo::SetName(std::string const & id)
|
||||||
{
|
{
|
||||||
if (id.empty() && WarningsAsErrors)
|
ScriptAssert(!id.empty(), "Name cannot be blank", ERROR_MODE::TERMINATE);
|
||||||
throw TENScriptException("Name cannot be blank");
|
|
||||||
|
|
||||||
// remove the old name if we have one
|
// remove the old name if we have one
|
||||||
s_callbackRemoveName(m_camera.luaName);
|
s_callbackRemoveName(m_camera.luaName);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "GameScriptItemInfo.h"
|
#include "GameScriptItemInfo.h"
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
#include "objectslist.h"
|
#include "objectslist.h"
|
||||||
|
@ -19,8 +20,6 @@ pickups, and Lara herself.
|
||||||
@pragma nostrip
|
@pragma nostrip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
constexpr auto LUA_CLASS_NAME{ "ItemInfo" };
|
constexpr auto LUA_CLASS_NAME{ "ItemInfo" };
|
||||||
|
|
||||||
static auto index_error = index_error_maker(GameScriptItemInfo, LUA_CLASS_NAME);
|
static auto index_error = index_error_maker(GameScriptItemInfo, LUA_CLASS_NAME);
|
||||||
|
@ -294,8 +293,7 @@ std::string GameScriptItemInfo::GetName() const
|
||||||
|
|
||||||
void GameScriptItemInfo::SetName(std::string const & id)
|
void GameScriptItemInfo::SetName(std::string const & id)
|
||||||
{
|
{
|
||||||
if (id.empty() && WarningsAsErrors)
|
ScriptAssert(!id.empty(), "Name cannot be blank", ERROR_MODE::TERMINATE);
|
||||||
throw std::runtime_error("Name cannot be blank");
|
|
||||||
|
|
||||||
// remove the old name if we have one
|
// remove the old name if we have one
|
||||||
s_callbackRemoveName(m_item->luaName);
|
s_callbackRemoveName(m_item->luaName);
|
||||||
|
@ -347,8 +345,7 @@ void GameScriptItemInfo::SetHP(short hp)
|
||||||
if(Objects[m_item->objectNumber].intelligent &&
|
if(Objects[m_item->objectNumber].intelligent &&
|
||||||
(hp < 0 || hp > Objects[m_item->objectNumber].hitPoints))
|
(hp < 0 || hp > Objects[m_item->objectNumber].hitPoints))
|
||||||
{
|
{
|
||||||
if (WarningsAsErrors)
|
ScriptAssert(false, "Invalid value: " + hp);
|
||||||
throw TENScriptException("invalid HP");
|
|
||||||
if (hp < 0)
|
if (hp < 0)
|
||||||
{
|
{
|
||||||
hp = 0;
|
hp = 0;
|
||||||
|
@ -484,8 +481,8 @@ void GameScriptItemInfo::SetRoom(short room)
|
||||||
{
|
{
|
||||||
if (room < 0 || static_cast<size_t>(room) >= g_Level.Rooms.size())
|
if (room < 0 || static_cast<size_t>(room) >= g_Level.Rooms.size())
|
||||||
{
|
{
|
||||||
if (WarningsAsErrors)
|
ScriptAssert(false, "Invalid room number: " + room);
|
||||||
throw TENScriptException("invalid room number");
|
TENLog("Room number will not be set", LogLevel::Warning, LogConfig::All);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "GameScriptMeshInfo.h"
|
#include "GameScriptMeshInfo.h"
|
||||||
#include "GameScriptPosition.h"
|
#include "GameScriptPosition.h"
|
||||||
#include "GameScriptColor.h"
|
#include "GameScriptColor.h"
|
||||||
|
@ -11,8 +12,6 @@ Mesh info
|
||||||
@pragma nostrip
|
@pragma nostrip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
constexpr auto LUA_CLASS_NAME{ "MeshInfo" };
|
constexpr auto LUA_CLASS_NAME{ "MeshInfo" };
|
||||||
|
|
||||||
static auto index_error = index_error_maker(GameScriptMeshInfo, LUA_CLASS_NAME);
|
static auto index_error = index_error_maker(GameScriptMeshInfo, LUA_CLASS_NAME);
|
||||||
|
@ -88,8 +87,7 @@ std::string GameScriptMeshInfo::GetName() const
|
||||||
|
|
||||||
void GameScriptMeshInfo::SetName(std::string const & id)
|
void GameScriptMeshInfo::SetName(std::string const & id)
|
||||||
{
|
{
|
||||||
if (id.empty() && WarningsAsErrors)
|
ScriptAssert(!id.empty(), "Name cannot be blank", ERROR_MODE::TERMINATE);
|
||||||
throw TENScriptException("Name cannot be blank");
|
|
||||||
|
|
||||||
// remove the old name if we have one
|
// remove the old name if we have one
|
||||||
s_callbackRemoveName(m_mesh.luaName);
|
s_callbackRemoveName(m_mesh.luaName);
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
#define index_error_maker(CPP_TYPE, LUA_CLASS_NAME) [](CPP_TYPE & item, sol::object key) \
|
#define index_error_maker(CPP_TYPE, LUA_CLASS_NAME) [](CPP_TYPE & item, sol::object key) \
|
||||||
{ \
|
{ \
|
||||||
if (WarningsAsErrors) \
|
std::string err = "Attempted to read non-existant var \"" + key.as<std::string>() + "\" from " + LUA_CLASS_NAME; \
|
||||||
{ \
|
throw TENScriptException(err); \
|
||||||
std::string err = "Attempted to read non-existant var \"" + key.as<std::string>() + "\" from " + LUA_CLASS_NAME; \
|
|
||||||
throw std::runtime_error(err); \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S> using callbackSetName = std::function<bool(std::string const&, S identifier)>;
|
template <typename S> using callbackSetName = std::function<bool(std::string const&, S identifier)>;
|
||||||
|
@ -37,20 +34,13 @@ protected:
|
||||||
// default callbacks
|
// default callbacks
|
||||||
template <typename T, typename S> callbackSetName<S> GameScriptNamedBase<T, S>::s_callbackSetName = [](std::string const& n, S identifier) {
|
template <typename T, typename S> callbackSetName<S> GameScriptNamedBase<T, S>::s_callbackSetName = [](std::string const& n, S identifier) {
|
||||||
std::string err = "\"Set Name\" callback is not set.";
|
std::string err = "\"Set Name\" callback is not set.";
|
||||||
if (WarningsAsErrors)
|
throw TENScriptException(err);
|
||||||
{
|
|
||||||
throw TENScriptException(err);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename S> callbackRemoveName GameScriptNamedBase<T, S>::s_callbackRemoveName = [](std::string const& n) {
|
template <typename T, typename S> callbackRemoveName GameScriptNamedBase<T, S>::s_callbackRemoveName = [](std::string const& n) {
|
||||||
std::string err = "\"Remove Name\" callback is not set.";
|
std::string err = "\"Remove Name\" callback is not set.";
|
||||||
if (WarningsAsErrors)
|
throw TENScriptException(err);
|
||||||
{
|
|
||||||
throw TENScriptException(err);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "GameScriptSinkInfo.h"
|
#include "GameScriptSinkInfo.h"
|
||||||
#include "GameScriptPosition.h"
|
#include "GameScriptPosition.h"
|
||||||
#include <sol.hpp>
|
#include <sol.hpp>
|
||||||
|
@ -10,8 +11,6 @@ Sink info
|
||||||
@pragma nostrip
|
@pragma nostrip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
constexpr auto LUA_CLASS_NAME{ "SinkInfo" };
|
constexpr auto LUA_CLASS_NAME{ "SinkInfo" };
|
||||||
|
|
||||||
static auto index_error = index_error_maker(GameScriptSinkInfo, LUA_CLASS_NAME);
|
static auto index_error = index_error_maker(GameScriptSinkInfo, LUA_CLASS_NAME);
|
||||||
|
@ -71,8 +70,7 @@ std::string GameScriptSinkInfo::GetName() const
|
||||||
|
|
||||||
void GameScriptSinkInfo::SetName(std::string const & id)
|
void GameScriptSinkInfo::SetName(std::string const & id)
|
||||||
{
|
{
|
||||||
if (id.empty() && WarningsAsErrors)
|
ScriptAssert(!id.empty(), "Name cannot be blank", ERROR_MODE::TERMINATE);
|
||||||
throw TENScriptException("Name cannot be blank");
|
|
||||||
|
|
||||||
// remove the old name if we have one
|
// remove the old name if we have one
|
||||||
s_callbackRemoveName(m_sink.luaName);
|
s_callbackRemoveName(m_sink.luaName);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
#include "ScriptAssert.h"
|
||||||
#include "GameScriptSoundSourceInfo.h"
|
#include "GameScriptSoundSourceInfo.h"
|
||||||
#include "GameScriptPosition.h"
|
#include "GameScriptPosition.h"
|
||||||
/***
|
/***
|
||||||
|
@ -8,8 +9,6 @@ Sound source info
|
||||||
@pragma nostrip
|
@pragma nostrip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern bool const WarningsAsErrors;
|
|
||||||
|
|
||||||
static constexpr auto LUA_CLASS_NAME{ "SoundSourceInfo" };
|
static constexpr auto LUA_CLASS_NAME{ "SoundSourceInfo" };
|
||||||
|
|
||||||
static auto index_error = index_error_maker(GameScriptSoundSourceInfo, LUA_CLASS_NAME);
|
static auto index_error = index_error_maker(GameScriptSoundSourceInfo, LUA_CLASS_NAME);
|
||||||
|
@ -67,8 +66,7 @@ std::string GameScriptSoundSourceInfo::GetName() const
|
||||||
|
|
||||||
void GameScriptSoundSourceInfo::SetName(std::string const & id)
|
void GameScriptSoundSourceInfo::SetName(std::string const & id)
|
||||||
{
|
{
|
||||||
if (id.empty() && WarningsAsErrors)
|
ScriptAssert(!id.empty(), "Name cannot be blank", ERROR_MODE::TERMINATE);
|
||||||
throw TENScriptException("Name cannot be blank");
|
|
||||||
|
|
||||||
// remove the old name if we have one
|
// remove the old name if we have one
|
||||||
s_callbackRemoveName(m_soundSource.luaName);
|
s_callbackRemoveName(m_soundSource.luaName);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue