File diff r24528:a7298f737f00 → r24529:3dec691db49a
src/script/script_info.cpp
Show inline comments
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file script_info.cpp Implementation of ScriptInfo. */
 

	
 
#include "../stdafx.h"
 
#include "../settings_type.h"
 

	
 
#include "squirrel_helper.hpp"
 

	
 
#include "script_info.hpp"
 
#include "script_scanner.hpp"
 

	
 
#include "../safeguards.h"
 

	
 
ScriptInfo::~ScriptInfo()
 
{
 
	/* Free all allocated strings */
 
	for (const auto &item : this->config_list) {
 
		free(item.name);
 
		free(item.description);
 
		if (item.labels != nullptr) {
 
			for (auto &lbl_map : *item.labels) {
 
				free(lbl_map.second);
 
			}
 
			delete item.labels;
 
		}
 
	}
 
	this->config_list.clear();
 

	
 
	free(this->author);
 
	free(this->name);
 
	free(this->short_name);
 
	free(this->description);
 
	free(this->date);
 
	free(this->instance_name);
 
	free(this->url);
 
	free(this->main_script);
 
	free(this->tar_file);
 
	free(this->SQ_instance);
 
}
 

	
 
bool ScriptInfo::CheckMethod(const char *name) const
 
{
 
	if (!this->engine->MethodExists(*this->SQ_instance, name)) {
 
		char error[1024];
 
		seprintf(error, lastof(error), "your info.nut/library.nut doesn't have the method '%s'", name);
 
		this->engine->ThrowError(error);
 
		return false;
 
	}
 
	return true;
 
}
 

	
 
/* static */ SQInteger ScriptInfo::Constructor(HSQUIRRELVM vm, ScriptInfo *info)
 
{
 
	/* Set some basic info from the parent */
 
	info->SQ_instance = MallocT<SQObject>(1);
 
	Squirrel::GetInstance(vm, info->SQ_instance, 2);
 
	/* Make sure the instance stays alive over time */
 
	sq_addref(vm, info->SQ_instance);
 

	
 
	info->scanner = (ScriptScanner *)Squirrel::GetGlobalPointer(vm);
 
	info->engine = info->scanner->GetEngine();
 

	
 
	/* Ensure the mandatory functions exist */
 
	static const char * const required_functions[] = {
 
		"GetAuthor",
 
		"GetName",
 
		"GetShortName",
 
		"GetDescription",
 
		"GetVersion",
 
		"GetDate",
 
		"CreateInstance",
 
	};
 
	for (size_t i = 0; i < lengthof(required_functions); i++) {
 
		if (!info->CheckMethod(required_functions[i])) return SQ_ERROR;
 
	}
 

	
 
	/* Get location information of the scanner */
 
	info->main_script = stredup(info->scanner->GetMainScript());
 
	const char *tar_name = info->scanner->GetTarFile();
 
	if (tar_name != nullptr) info->tar_file = stredup(tar_name);
 
	info->main_script = info->scanner->GetMainScript();
 
	info->tar_file = info->scanner->GetTarFile();
 

	
 
	/* Cache the data the info file gives us. */
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAuthor", &info->author, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetName", &info->name, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetShortName", &info->short_name, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetDescription", &info->description, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetDate", &info->date, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!info->engine->CallIntegerMethod(*info->SQ_instance, "GetVersion", &info->version, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "CreateInstance", &info->instance_name, MAX_CREATEINSTANCE_OPS)) return SQ_ERROR;
 

	
 
	/* The GetURL function is optional. */
 
	if (info->engine->MethodExists(*info->SQ_instance, "GetURL")) {
 
		if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetURL", &info->url, MAX_GET_OPS)) return SQ_ERROR;
 
	}
 

	
 
	/* Check if we have settings */
 
	if (info->engine->MethodExists(*info->SQ_instance, "GetSettings")) {
 
		if (!info->GetSettings()) return SQ_ERROR;
 
	}
 

	
 
	return 0;
 
}
 

	
 
bool ScriptInfo::GetSettings()
 
{
 
	return this->engine->CallMethod(*this->SQ_instance, "GetSettings", nullptr, MAX_GET_SETTING_OPS);
 
}
 

	
 
SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
 
{
 
	ScriptConfigItem config;
 
	memset(&config, 0, sizeof(config));
 
	config.max_value = 1;
 
	config.step_size = 1;
 
	uint items = 0;
 

	
 
	/* Read the table, and find all properties we care about */
 
	sq_pushnull(vm);
 
	while (SQ_SUCCEEDED(sq_next(vm, -2))) {
 
		const SQChar *key;
 
		if (SQ_FAILED(sq_getstring(vm, -2, &key))) return SQ_ERROR;
 
		ValidateString(key);
 

	
 
		if (strcmp(key, "name") == 0) {
 
			const SQChar *sqvalue;
 
			if (SQ_FAILED(sq_getstring(vm, -1, &sqvalue))) return SQ_ERROR;
 
			char *name = stredup(sqvalue);
 
			char *s;