ADDON_STATUS CAddonDll::Create(ADDON_TYPE type, void* funcTable, void* info) { /* ensure that a previous instance is destroyed */ Destroy(); if (!funcTable) return ADDON_STATUS_PERMANENT_FAILURE; CLog::Log(LOGDEBUG, "ADDON: Dll Initializing - %s", Name().c_str()); m_initialized = false; if (!LoadDll()) return ADDON_STATUS_PERMANENT_FAILURE; /* Check requested instance version on add-on */ if (!CheckAPIVersion(type)) return ADDON_STATUS_PERMANENT_FAILURE; /* Check versions about global parts on add-on (parts used on all types) */ for (unsigned int id = ADDON_GLOBAL_MAIN; id <= ADDON_GLOBAL_MAX; ++id) { if (!CheckAPIVersion(id)) return ADDON_STATUS_PERMANENT_FAILURE; } /* Load add-on function table (written by add-on itself) */ m_pDll->GetAddon(funcTable); /* Allocate the helper function class to allow crosstalk over helper libraries */ m_pHelpers = new CAddonInterfaces(this); /* Call Create to make connections, initializing data or whatever is needed to become the AddOn running */ ADDON_STATUS status = m_pDll->Create(m_pHelpers->GetCallbacks(), info); if (status == ADDON_STATUS_OK) { m_initialized = true; } else if (status == ADDON_STATUS_NEED_SETTINGS) { status = TransferSettings(); if (status == ADDON_STATUS_OK) m_initialized = true; else new CAddonStatusHandler(ID(), status, "", false); } else { // Addon failed initialization CLog::Log(LOGERROR, "ADDON: Dll %s - Client returned bad status (%i) from Create and is not usable", Name().c_str(), status); std::string heading = StringUtils::Format("%s: %s", CAddonInfo::TranslateType(Type(), true).c_str(), Name().c_str()); HELPERS::ShowOKDialogLines(CVariant{ heading }, CVariant{ 24070 }, CVariant{ 24071 }); } return status; }
/* static */ SQInteger GameInfo::Constructor(HSQUIRRELVM vm) { /* Get the GameInfo */ SQUserPointer instance = NULL; if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, _SC("Pass an instance of a child class of GameInfo to RegisterGame")); GameInfo *info = (GameInfo *)instance; SQInteger res = ScriptInfo::Constructor(vm, info); if (res != 0) return res; if (info->engine->MethodExists(*info->SQ_instance, "MinVersionToLoad")) { if (!info->engine->CallIntegerMethod(*info->SQ_instance, "MinVersionToLoad", &info->min_loadable_version, MAX_GET_OPS)) return SQ_ERROR; } else { info->min_loadable_version = info->GetVersion(); } /* When there is an IsSelectable function, call it. */ if (info->engine->MethodExists(*info->SQ_instance, "IsDeveloperOnly")) { if (!info->engine->CallBoolMethod(*info->SQ_instance, "IsDeveloperOnly", &info->is_developer_only, MAX_GET_OPS)) return SQ_ERROR; } else { info->is_developer_only = false; } /* Try to get the API version the AI is written for. */ if (!info->CheckMethod("GetAPIVersion")) return SQ_ERROR; if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR; if (!CheckAPIVersion(info->api_version)) { DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion()); return SQ_ERROR; } /* Remove the link to the real instance, else it might get deleted by RegisterGame() */ sq_setinstanceup(vm, 2, NULL); /* Register the Game to the base system */ info->GetScanner()->RegisterScript(info); return 0; }
ADDON_STATUS CAddonDll::Create(void* funcTable, void* info) { /* ensure that a previous instance is destroyed */ Destroy(); if (!funcTable) return ADDON_STATUS_PERMANENT_FAILURE; CLog::Log(LOGDEBUG, "ADDON: Dll Initializing - %s", Name().c_str()); m_initialized = false; if (!LoadDll()) return ADDON_STATUS_PERMANENT_FAILURE; /* Load add-on function table (written by add-on itself) */ m_pDll->GetAddon(funcTable); if (!CheckAPIVersion()) return ADDON_STATUS_PERMANENT_FAILURE; /* Allocate the helper function class to allow crosstalk over helper libraries */ m_pHelpers = new CAddonInterfaces(this); /* Call Create to make connections, initializing data or whatever is needed to become the AddOn running */ ADDON_STATUS status = m_pDll->Create(m_pHelpers->GetCallbacks(), info); if (status == ADDON_STATUS_OK) { m_initialized = true; } else if ((status == ADDON_STATUS_NEED_SETTINGS) || (status == ADDON_STATUS_NEED_SAVEDSETTINGS)) { m_needsavedsettings = (status == ADDON_STATUS_NEED_SAVEDSETTINGS); if ((status = TransferSettings()) == ADDON_STATUS_OK) m_initialized = true; else new CAddonStatusHandler(ID(), status, "", false); } else { // Addon failed initialization CLog::Log(LOGERROR, "ADDON: Dll %s - Client returned bad status (%i) from Create and is not usable", Name().c_str(), status); CGUIDialogOK* pDialog = g_windowManager.GetWindow<CGUIDialogOK>(WINDOW_DIALOG_OK); if (pDialog) { std::string heading = StringUtils::Format("%s: %s", TranslateType(Type(), true).c_str(), Name().c_str()); pDialog->SetHeading(CVariant{heading}); pDialog->SetLine(1, CVariant{24070}); pDialog->SetLine(2, CVariant{24071}); pDialog->Open(); } } return status; }
/* static */ SQInteger AIInfo::Constructor(HSQUIRRELVM vm) { /* Get the AIInfo */ SQUserPointer instance = NULL; if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, _SC("Pass an instance of a child class of AIInfo to RegisterAI")); AIInfo *info = (AIInfo *)instance; SQInteger res = AIFileInfo::Constructor(vm, info); if (res != 0) return res; AIConfigItem config = _start_date_config; config.name = strdup(config.name); config.description = strdup(config.description); info->config_list.push_back(config); /* Check if we have settings */ if (info->engine->MethodExists(*info->SQ_instance, "GetSettings")) { if (!info->GetSettings()) return SQ_ERROR; } if (info->engine->MethodExists(*info->SQ_instance, "MinVersionToLoad")) { if (!info->engine->CallIntegerMethod(*info->SQ_instance, "MinVersionToLoad", &info->min_loadable_version, MAX_GET_SETTING_OPS)) return SQ_ERROR; } else { info->min_loadable_version = info->GetVersion(); } /* When there is an UseAsRandomAI function, call it. */ if (info->engine->MethodExists(*info->SQ_instance, "UseAsRandomAI")) { if (!info->engine->CallBoolMethod(*info->SQ_instance, "UseAsRandomAI", &info->use_as_random, MAX_GET_SETTING_OPS)) return SQ_ERROR; } else { info->use_as_random = true; } /* Try to get the API version the AI is written for. */ if (info->engine->MethodExists(*info->SQ_instance, "GetAPIVersion")) { if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_SETTING_OPS)) return SQ_ERROR; if (!CheckAPIVersion(info->api_version)) { DEBUG(ai, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion()); return SQ_ERROR; } } else { info->api_version = strdup("0.7"); } /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ sq_setinstanceup(vm, 2, NULL); /* Register the AI to the base system */ info->base->RegisterAI(info); return 0; }
ADDON_STATUS CAddonDll::Create(KODI_HANDLE firstKodiInstance) { CLog::Log(LOGDEBUG, "ADDON: Dll Initializing - %s", Name().c_str()); m_initialized = false; if (!LoadDll()) { return ADDON_STATUS_PERMANENT_FAILURE; } /* Check versions about global parts on add-on (parts used on all types) */ for (unsigned int id = ADDON_GLOBAL_MAIN; id <= ADDON_GLOBAL_MAX; ++id) { if (!CheckAPIVersion(id)) return ADDON_STATUS_PERMANENT_FAILURE; } /* Allocate the helper function class to allow crosstalk over helper add-on headers */ if (!InitInterface(firstKodiInstance)) return ADDON_STATUS_PERMANENT_FAILURE; /* Call Create to make connections, initializing data or whatever is needed to become the AddOn running */ ADDON_STATUS status = m_pDll->Create(&m_interface, nullptr); if (status == ADDON_STATUS_OK) { m_initialized = true; } else if (status == ADDON_STATUS_NEED_SETTINGS) { if ((status = TransferSettings()) == ADDON_STATUS_OK) m_initialized = true; else new CAddonStatusHandler(ID(), status, "", false); } else { // Addon failed initialization CLog::Log(LOGERROR, "ADDON: Dll %s - Client returned bad status (%i) from Create and is not usable", Name().c_str(), status); // @todo currently a copy and paste from other function and becomes improved. std::string heading = StringUtils::Format("%s: %s", CAddonInfo::TranslateType(Type(), true).c_str(), Name().c_str()); HELPERS::ShowOKDialogLines(CVariant{ heading }, CVariant{ 24070 }, CVariant{ 24071 }); } return status; }
ADDON_STATUS CAddonDll::CreateInstance(ADDON_TYPE instanceType, const std::string& instanceID, KODI_HANDLE instance, KODI_HANDLE parentInstance) { ADDON_STATUS status = ADDON_STATUS_OK; if (!m_initialized) status = Create(instance); if (status != ADDON_STATUS_OK) return status; /* Check version of requested instance type */ if (!CheckAPIVersion(instanceType)) return ADDON_STATUS_PERMANENT_FAILURE; KODI_HANDLE addonInstance; status = m_interface.toAddon->create_instance(instanceType, instanceID.c_str(), instance, &addonInstance, parentInstance); if (status == ADDON_STATUS_OK) { m_usedInstances[instanceID] = std::make_pair(instanceType, addonInstance); } return status; }