summaryrefslogblamecommitdiffstats
path: root/src/Plugin.cpp
blob: 9641e0ffd4e59a22bb4916a5aaac4bf81f994870 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11





                          




                        






                                                             
                                                 








                            
                                                
                                     
                                                                       


                                                                                   

                                                                                                   






                                                                                                                                    
                                           


                                     










                                         

 

                           









                                                  


















                                                   



                                                                    


                                                           

 

                                                                     



                                         

                              


         

                                                            









                                                               












                                                         
#include "Plugin.hpp"

#include <vector>

#include <easylogging++.h>
#include <sol.hpp>
#include <optick.h>

#include "GameState.hpp"
#include "Game.hpp"


struct Plugin {
	const std::string name;
	const std::string displayName;
	const std::function<void()> onLoad;
	const std::function<void()> onUnload;
	const std::function<void(std::string)> onChangeState;
	const std::function<void(double)> onTick;
};


std::vector<Plugin> plugins;
sol::state lua;


namespace PluginApi {

	void RegisterPlugin(sol::table plugin) {
		Plugin nativePlugin {
				plugin["name"].get_or<std::string>(""),
				plugin["displayName"].get_or<std::string>(""),
				plugin["onLoad"].get_or(std::function<void()>()),
				plugin["onUnload"].get_or(std::function<void()>()),
				plugin["onChangeState"].get_or(std::function<void(std::string)>()),
				plugin["onTick"].get_or(std::function<void(double)>())
		};
		plugins.push_back(nativePlugin);
		nativePlugin.onLoad();
		
		LOG(INFO) << "Loaded plugin " << (!nativePlugin.displayName.empty() ? nativePlugin.displayName : nativePlugin.name);
	}

	void LogWarning(std::string text) {
		LOG(WARNING) << text;
	}

	void LogInfo(std::string text) {
		LOG(INFO) << text;
	}

	void LogError(std::string text) {
		LOG(ERROR) << text;
	}

	GameState *GetGameState() {
		return ::GetGameState();
	}
}

void PluginSystem::Init() {
	OPTICK_EVENT();
	LOG(INFO) << "Initializing plugin system";
	for (Plugin &plugin : plugins) {
		if (plugin.onUnload)
			plugin.onUnload();
	}

	plugins.clear();
	lua = sol::state();
	lua.open_libraries();

	lua.new_usertype<Entity>("Entity",
		"pos", &Entity::pos);

	lua.new_usertype<GameState>("GameState",
		"GetPlayer", &GameState::GetPlayer,
		"GetWorld", &GameState::GetWorld);

	lua.new_usertype<World>("World");

	lua.new_usertype<Vector>("Vector",
		"x", &Vector::x,
		"y", &Vector::y,
		"z", &Vector::z);

	lua.new_usertype<VectorF>("VectorF",
		"x", &VectorF::x,
		"y", &VectorF::y,
		"z", &VectorF::z);

	sol::table apiTable = lua["AC"].get_or_create<sol::table>();

	apiTable["RegisterPlugin"] = PluginApi::RegisterPlugin;
	apiTable["LogWarning"] = PluginApi::LogWarning;
	apiTable["LogInfo"] = PluginApi::LogInfo;
	apiTable["LogError"] = PluginApi::LogError;
	apiTable["GetGameState"] = PluginApi::GetGameState;
}

void PluginSystem::Execute(const std::string &luaCode, bool except) {
	OPTICK_EVENT();
	try {
		lua.safe_script(luaCode);
	} catch (sol::error &e) {
		LOG(ERROR) << e.what();
		if (except)
			throw;
	}
}

void PluginSystem::CallOnChangeState(std::string newState) {
	OPTICK_EVENT();
	for (Plugin &plugin : plugins) {
		if (plugin.onChangeState)
			try {
				plugin.onChangeState(newState);
			}
			catch (sol::error &e) {
				LOG(ERROR) << e.what();
			}
	}
}

void PluginSystem::CallOnTick(double deltaTime) {
	OPTICK_EVENT();
	for (Plugin& plugin : plugins) {
		if (plugin.onTick)
			try {
				plugin.onTick(deltaTime);
			}
			catch (sol::error &e) {
				LOG(ERROR) << e.what();
			}
	}
}