content menu moved to xml (no icons yet)
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
<panel size='550' color='0' padding='8' interval='5'>
|
||||||
|
<panel id='packs_panel' size='540,10' color='0,0,0,50' max-length='400'>
|
||||||
|
<!-- content is generated in script -->
|
||||||
|
</panel>
|
||||||
|
<button onclick='menu:back()' padding='10'>@Back</button>
|
||||||
|
</panel>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
function add_pack(packid, packinfo)
|
||||||
|
local callback = string.format('core.add_packs({%q})', packid)
|
||||||
|
packinfo.id = packid
|
||||||
|
packinfo.callback = callback
|
||||||
|
packinfo.icon = "gui/no_icon"
|
||||||
|
document.packs_panel:add(gui.template("pack", packinfo))
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_open()
|
||||||
|
local packs = pack.get_available()
|
||||||
|
for i,id in ipairs(packs) do
|
||||||
|
add_pack(id, pack.get_info(id))
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<panel size='550' color='0' padding='8' interval='5'>
|
<panel size='550' color='0' padding='8' interval='5'>
|
||||||
<panel id='packs_panel' size='540,10' color='0,0,0,50' max-length='400'>
|
<panel id='packs_panel' size='540,10' color='0,0,0,50' max-length='400'>
|
||||||
<!-- content is generated in script -->
|
<!-- content is generated in script -->
|
||||||
</panel>
|
</panel>
|
||||||
|
<button onclick='menu.page = "add_packs"' padding='10'>@Add</button>
|
||||||
<button onclick='menu:back()' padding='10'>@Back</button>
|
<button onclick='menu:back()' padding='10'>@Back</button>
|
||||||
</panel>
|
</panel>
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
function add_pack(packid, packinfo)
|
function add_pack(packid, packinfo)
|
||||||
document.packs_panel:add(gui.template("pack", {
|
local remover = ''
|
||||||
id=packid,
|
if packid ~= "base" then
|
||||||
title=packinfo.title,
|
remover = string.format('core.remove_packs({%q})', packid)
|
||||||
description=packinfo.description,
|
end
|
||||||
icon="gui/no_icon",
|
if packinfo.has_indices then
|
||||||
creator=packinfo.creator,
|
packid = packid.."*"
|
||||||
remover='0'
|
end
|
||||||
}))
|
packinfo.id = packid
|
||||||
|
packinfo.remover = remover
|
||||||
|
packinfo.icon = "gui/no_icon"
|
||||||
|
document.packs_panel:add(gui.template("pack", packinfo))
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_open()
|
function on_open()
|
||||||
|
|||||||
@@ -204,7 +204,8 @@ end
|
|||||||
function gui.template(name, params)
|
function gui.template(name, params)
|
||||||
local text = file.read(file.find("layouts/templates/"..name..".xml"))
|
local text = file.read(file.find("layouts/templates/"..name..".xml"))
|
||||||
for k,v in pairs(params) do
|
for k,v in pairs(params) do
|
||||||
text = text:gsub("(%%{"..k.."})", tostring(v))
|
local arg = tostring(v):gsub("'", "\\'"):gsub('"', '\\"')
|
||||||
|
text = text:gsub("(%%{"..k.."})", arg)
|
||||||
end
|
end
|
||||||
text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''")
|
text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''")
|
||||||
text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"")
|
text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"")
|
||||||
|
|||||||
+1
-1
@@ -179,8 +179,8 @@ Engine::~Engine() {
|
|||||||
logger.info() << "shutting down";
|
logger.info() << "shutting down";
|
||||||
if (screen) {
|
if (screen) {
|
||||||
screen->onEngineShutdown();
|
screen->onEngineShutdown();
|
||||||
|
screen.reset();
|
||||||
}
|
}
|
||||||
screen.reset();
|
|
||||||
content.reset();
|
content.reset();
|
||||||
assets.reset();
|
assets.reset();
|
||||||
audio::close();
|
audio::close();
|
||||||
|
|||||||
+10
-18
@@ -219,11 +219,17 @@ void menus::delete_world(std::string name, Engine* engine) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_page_loader(Engine* engine, const std::string& name) {
|
void menus::create_menus(Engine* engine) {
|
||||||
|
menus::generatorID = WorldGenerators::getDefaultGeneratorID();
|
||||||
|
create_new_world_panel(engine);
|
||||||
|
create_settings_panel(engine);
|
||||||
|
create_world_generators_panel(engine);
|
||||||
|
|
||||||
auto menu = engine->getGUI()->getMenu();
|
auto menu = engine->getGUI()->getMenu();
|
||||||
auto file = engine->getResPaths()->find("layouts/pages/"+name+".xml");
|
menu->setPageLoader([=](auto name) {
|
||||||
auto fullname = "core:pages/"+name;
|
auto file = engine->getResPaths()->find("layouts/pages/"+name+".xml");
|
||||||
menu->addSupplier(name, [=]() {
|
auto fullname = "core:pages/"+name;
|
||||||
|
|
||||||
auto document = UiDocument::read(0, fullname, file).release();
|
auto document = UiDocument::read(0, fullname, file).release();
|
||||||
engine->getAssets()->store(document, fullname);
|
engine->getAssets()->store(document, fullname);
|
||||||
scripting::on_ui_open(document, nullptr, glm::ivec3());
|
scripting::on_ui_open(document, nullptr, glm::ivec3());
|
||||||
@@ -231,21 +237,7 @@ static void add_page_loader(Engine* engine, const std::string& name) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void menus::create_menus(Engine* engine) {
|
|
||||||
menus::generatorID = WorldGenerators::getDefaultGeneratorID();
|
|
||||||
create_new_world_panel(engine);
|
|
||||||
create_settings_panel(engine);
|
|
||||||
add_page_loader(engine, "languages");
|
|
||||||
create_world_generators_panel(engine);
|
|
||||||
add_page_loader(engine, "main");
|
|
||||||
add_page_loader(engine, "404");
|
|
||||||
add_page_loader(engine, "content");
|
|
||||||
}
|
|
||||||
|
|
||||||
void menus::refresh_menus(Engine* engine) {
|
void menus::refresh_menus(Engine* engine) {
|
||||||
create_new_world_panel(engine);
|
create_new_world_panel(engine);
|
||||||
create_world_generators_panel(engine);
|
create_world_generators_panel(engine);
|
||||||
add_page_loader(engine, "main");
|
|
||||||
add_page_loader(engine, "404");
|
|
||||||
add_page_loader(engine, "settings-audio");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,95 +19,6 @@
|
|||||||
|
|
||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
std::shared_ptr<Container> create_pack_panel(
|
|
||||||
const ContentPack& pack,
|
|
||||||
Engine* engine,
|
|
||||||
packconsumer callback,
|
|
||||||
packconsumer remover
|
|
||||||
) {
|
|
||||||
auto assets = engine->getAssets();
|
|
||||||
auto packpanel = std::dynamic_pointer_cast<Container>(guiutil::create(
|
|
||||||
"<container size='540,80' color='#0F1E2DB2'></container>"
|
|
||||||
));
|
|
||||||
if (callback) {
|
|
||||||
packpanel->listenAction([=](GUI*) {
|
|
||||||
callback(pack);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
auto runtime = engine->getContent() ? engine->getContent()->getPackRuntime(pack.id) : nullptr;
|
|
||||||
auto idtext = (runtime && runtime->getStats().hasSavingContent())
|
|
||||||
? "*["+pack.id+"]"
|
|
||||||
: "["+pack.id+"]";
|
|
||||||
|
|
||||||
packpanel->add(guiutil::create(
|
|
||||||
"<label pos='215,2' color='#FFFFFF80' size='300,25' align='right'>"
|
|
||||||
+idtext+
|
|
||||||
"</label>"
|
|
||||||
));
|
|
||||||
packpanel->add(guiutil::create(
|
|
||||||
"<label pos='78,6'>"+pack.title+"</label>"
|
|
||||||
));
|
|
||||||
|
|
||||||
if (!pack.creator.empty()) {
|
|
||||||
packpanel->add(guiutil::create(
|
|
||||||
"<label color='#CCFFE5B2' size='300,20' align='right' pos='215,60'>"
|
|
||||||
+pack.creator+
|
|
||||||
"</label>"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
packpanel->add(guiutil::create(
|
|
||||||
"<label pos='80,28' color='#FFFFFFB2'>"
|
|
||||||
+pack.description+
|
|
||||||
"</label>"
|
|
||||||
));
|
|
||||||
|
|
||||||
std::string icon = pack.id+".icon";
|
|
||||||
if (assets->getTexture(icon) == nullptr) {
|
|
||||||
auto iconfile = pack.folder/fs::path("icon.png");
|
|
||||||
if (fs::is_regular_file(iconfile)) {
|
|
||||||
auto image = imageio::read(iconfile.string());
|
|
||||||
assets->store(Texture::from(image.get()), icon);
|
|
||||||
} else {
|
|
||||||
icon = "gui/no_icon";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
packpanel->add(std::make_shared<Image>(icon, glm::vec2(64)), glm::vec2(8));
|
|
||||||
|
|
||||||
if (remover && pack.id != "base") {
|
|
||||||
auto rembtn = guiutil::create(
|
|
||||||
"<button color='#00000000' hover-color='#FFFFFF2B'>"
|
|
||||||
"<image src='gui/cross' size='32,32'/>"
|
|
||||||
"</button>"
|
|
||||||
);
|
|
||||||
rembtn->listenAction([=](GUI* gui) {
|
|
||||||
remover(pack);
|
|
||||||
});
|
|
||||||
packpanel->add(rembtn, glm::vec2(470, 22));
|
|
||||||
}
|
|
||||||
return packpanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Panel> menus::create_packs_panel(
|
|
||||||
const std::vector<ContentPack>& packs,
|
|
||||||
Engine* engine,
|
|
||||||
bool backbutton,
|
|
||||||
packconsumer callback,
|
|
||||||
packconsumer remover
|
|
||||||
){
|
|
||||||
auto panel = std::dynamic_pointer_cast<Panel>(guiutil::create(
|
|
||||||
"<panel size='550,200' interval='5' color='#FFFFFF11' max-length='400' scrollable='true'>"
|
|
||||||
"</panel>"
|
|
||||||
));
|
|
||||||
for (auto& pack : packs) {
|
|
||||||
panel->add(create_pack_panel(pack, engine, callback, remover));
|
|
||||||
}
|
|
||||||
if (backbutton) {
|
|
||||||
panel->add(guiutil::backButton(engine->getGUI()->getMenu()));
|
|
||||||
}
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reopen_world(Engine* engine, World* world) {
|
static void reopen_world(Engine* engine, World* world) {
|
||||||
std::string wname = world->wfile->getFolder().stem().u8string();
|
std::string wname = world->wfile->getFolder().stem().u8string();
|
||||||
engine->setScreen(nullptr);
|
engine->setScreen(nullptr);
|
||||||
@@ -191,43 +102,6 @@ void menus::add_packs(
|
|||||||
reopen_world(engine, world);
|
reopen_world(engine, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_content_panel(Engine* engine, LevelController* controller) {
|
|
||||||
auto level = controller->getLevel();
|
|
||||||
auto menu = engine->getGUI()->getMenu();
|
|
||||||
auto mainPanel = menus::create_page(engine, "content", 550, 0.0f, 5);
|
|
||||||
|
|
||||||
PacksManager manager = engine->createPacksManager(level->getWorld()->wfile->getFolder());
|
|
||||||
manager.scan();
|
|
||||||
|
|
||||||
std::vector<ContentPack> scanned = manager.getAll(manager.getAllNames());
|
|
||||||
for (const auto& pack : engine->getContentPacks()) {
|
|
||||||
for (size_t i = 0; i < scanned.size(); i++) {
|
|
||||||
if (scanned[i].id == pack.id) {
|
|
||||||
scanned.erase(scanned.begin()+i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto panel = menus::create_packs_panel(
|
|
||||||
engine->getContentPacks(), engine, false, nullptr,
|
|
||||||
[=](const ContentPack& pack) {
|
|
||||||
std::vector<std::string> packsToRemove {pack.id};
|
|
||||||
menus::remove_packs(engine, controller, packsToRemove);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
mainPanel->add(panel);
|
|
||||||
mainPanel->add(menus::create_button(
|
|
||||||
langs::get(L"Add", L"content"), glm::vec4(10.0f), glm::vec4(1), [=](GUI* gui) {
|
|
||||||
auto panel = menus::create_packs_panel(scanned, engine, true,
|
|
||||||
[=](const ContentPack& pack) {
|
|
||||||
menus::add_packs(engine, controller, {pack.id});
|
|
||||||
}, nullptr);
|
|
||||||
menu->addPage("content-packs", panel);
|
|
||||||
menu->setPage("content-packs");
|
|
||||||
}));
|
|
||||||
mainPanel->add(guiutil::backButton(menu));
|
|
||||||
}
|
|
||||||
|
|
||||||
void menus::create_pause_panel(Engine* engine, LevelController* controller) {
|
void menus::create_pause_panel(Engine* engine, LevelController* controller) {
|
||||||
auto menu = engine->getGUI()->getMenu();
|
auto menu = engine->getGUI()->getMenu();
|
||||||
auto panel = create_page(engine, "pause", 400, 0.0f, 1);
|
auto panel = create_page(engine, "pause", 400, 0.0f, 1);
|
||||||
@@ -236,7 +110,6 @@ void menus::create_pause_panel(Engine* engine, LevelController* controller) {
|
|||||||
menu->reset();
|
menu->reset();
|
||||||
}));
|
}));
|
||||||
panel->add(create_button(L"Content", glm::vec4(10.0f), glm::vec4(1), [=](GUI*) {
|
panel->add(create_button(L"Content", glm::vec4(10.0f), glm::vec4(1), [=](GUI*) {
|
||||||
//create_content_panel(engine, controller);
|
|
||||||
menu->setPage("content");
|
menu->setPage("content");
|
||||||
}));
|
}));
|
||||||
panel->add(guiutil::gotoButton(L"Settings", "settings", menu));
|
panel->add(guiutil::gotoButton(L"Settings", "settings", menu));
|
||||||
|
|||||||
@@ -268,11 +268,14 @@ void Menu::addSupplier(std::string name, supplier<std::shared_ptr<UINode>> pageS
|
|||||||
pageSuppliers[name] = pageSupplier;
|
pageSuppliers[name] = pageSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<UINode> Menu::fetchPage(std::string name) {
|
std::shared_ptr<UINode> Menu::fetchPage(const std::string& name) {
|
||||||
auto found = pages.find(name);
|
auto found = pages.find(name);
|
||||||
if (found == pages.end()) {
|
if (found == pages.end()) {
|
||||||
auto supplier = pageSuppliers.find(name);
|
auto supplier = pageSuppliers.find(name);
|
||||||
if (supplier == pageSuppliers.end()) {
|
if (supplier == pageSuppliers.end()) {
|
||||||
|
if (pagesLoader) {
|
||||||
|
return pagesLoader(name);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
return supplier->second();
|
return supplier->second();
|
||||||
@@ -318,6 +321,10 @@ void Menu::back() {
|
|||||||
setPage(page, false);
|
setPage(page, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::setPageLoader(page_loader_func loader) {
|
||||||
|
pagesLoader = loader;
|
||||||
|
}
|
||||||
|
|
||||||
Page& Menu::getCurrent() {
|
Page& Menu::getCurrent() {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,12 +94,15 @@ namespace gui {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using page_loader_func = std::function<std::shared_ptr<UINode>(const std::string& name)>;
|
||||||
|
|
||||||
class Menu : public Container {
|
class Menu : public Container {
|
||||||
protected:
|
protected:
|
||||||
std::unordered_map<std::string, Page> pages;
|
std::unordered_map<std::string, Page> pages;
|
||||||
std::stack<Page> pageStack;
|
std::stack<Page> pageStack;
|
||||||
Page current;
|
Page current;
|
||||||
std::unordered_map<std::string, supplier<std::shared_ptr<UINode>>> pageSuppliers;
|
std::unordered_map<std::string, supplier<std::shared_ptr<UINode>>> pageSuppliers;
|
||||||
|
page_loader_func pagesLoader = nullptr;
|
||||||
public:
|
public:
|
||||||
Menu();
|
Menu();
|
||||||
|
|
||||||
@@ -113,13 +116,16 @@ namespace gui {
|
|||||||
void setPage(std::string name, bool history=true);
|
void setPage(std::string name, bool history=true);
|
||||||
void setPage(Page page, bool history=true);
|
void setPage(Page page, bool history=true);
|
||||||
void addPage(std::string name, std::shared_ptr<UINode> panel);
|
void addPage(std::string name, std::shared_ptr<UINode> panel);
|
||||||
std::shared_ptr<UINode> fetchPage(std::string name);
|
std::shared_ptr<UINode> fetchPage(const std::string& name);
|
||||||
|
|
||||||
/// @brief Add page supplier used if page is not found
|
/// @brief Add page supplier used if page is not found
|
||||||
/// @param name page name
|
/// @param name page name
|
||||||
/// @param pageSupplier page supplier function
|
/// @param pageSupplier page supplier function
|
||||||
void addSupplier(std::string name, supplier<std::shared_ptr<UINode>> pageSupplier);
|
void addSupplier(std::string name, supplier<std::shared_ptr<UINode>> pageSupplier);
|
||||||
|
|
||||||
|
/// @brief Page loader is called if accessed page is not found
|
||||||
|
void setPageLoader(page_loader_func loader);
|
||||||
|
|
||||||
/// @brief Set page to previous saved in history
|
/// @brief Set page to previous saved in history
|
||||||
void back();
|
void back();
|
||||||
|
|
||||||
|
|||||||
@@ -102,18 +102,20 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (element->has("onclick")) {
|
if (element->has("onclick")) {
|
||||||
auto callback = scripting::create_runnable(
|
std::string text = element->attr("onclick").getText();
|
||||||
reader.getEnvironment().getId(),
|
if (!text.empty()) {
|
||||||
element->attr("onclick").getText(),
|
auto callback = scripting::create_runnable(
|
||||||
reader.getFilename()
|
reader.getEnvironment().getId(),
|
||||||
);
|
text,
|
||||||
node.listenAction([callback](GUI*) {
|
reader.getFilename()
|
||||||
callback();
|
);
|
||||||
});
|
node.listenAction([callback](GUI*) {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) {
|
static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) {
|
||||||
_readUINode(reader, element, container);
|
_readUINode(reader, element, container);
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,21 @@ static int l_remove_packs(lua_State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_add_packs(lua_State* L) {
|
||||||
|
if (!lua_istable(L, 1)) {
|
||||||
|
luaL_error(L, "strings array expected as an argument");
|
||||||
|
}
|
||||||
|
std::vector<std::string> packs;
|
||||||
|
int len = lua_objlen(L, 1);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
lua_rawgeti(L, -1, i+1);
|
||||||
|
packs.push_back(lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
menus::add_packs(scripting::engine, scripting::controller, packs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int l_get_bindings(lua_State* L) {
|
static int l_get_bindings(lua_State* L) {
|
||||||
auto& bindings = Events::bindings;
|
auto& bindings = Events::bindings;
|
||||||
lua_createtable(L, bindings.size(), 0);
|
lua_createtable(L, bindings.size(), 0);
|
||||||
@@ -116,6 +131,7 @@ const luaL_Reg corelib [] = {
|
|||||||
{"open_world", lua_wrap_errors<l_open_world>},
|
{"open_world", lua_wrap_errors<l_open_world>},
|
||||||
{"close_world", lua_wrap_errors<l_close_world>},
|
{"close_world", lua_wrap_errors<l_close_world>},
|
||||||
{"delete_world", lua_wrap_errors<l_delete_world>},
|
{"delete_world", lua_wrap_errors<l_delete_world>},
|
||||||
|
{"add_packs", lua_wrap_errors<l_add_packs>},
|
||||||
{"remove_packs", lua_wrap_errors<l_remove_packs>},
|
{"remove_packs", lua_wrap_errors<l_remove_packs>},
|
||||||
{"get_bindings", lua_wrap_errors<l_get_bindings>},
|
{"get_bindings", lua_wrap_errors<l_get_bindings>},
|
||||||
{"get_setting", lua_wrap_errors<l_get_setting>},
|
{"get_setting", lua_wrap_errors<l_get_setting>},
|
||||||
|
|||||||
@@ -214,11 +214,7 @@ static bool setattr(lua_State* L, gui::Menu* menu, const std::string& attr) {
|
|||||||
return false;
|
return false;
|
||||||
if (attr == "page") {
|
if (attr == "page") {
|
||||||
auto page = lua_tostring(L, 4);
|
auto page = lua_tostring(L, 4);
|
||||||
if (menu->has(page)) {
|
menu->setPage(page);
|
||||||
menu->setPage(page);
|
|
||||||
} else {
|
|
||||||
menu->setPage("404");
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -59,10 +59,12 @@ int main(int argc, char** argv) {
|
|||||||
catch (const initialize_error& err) {
|
catch (const initialize_error& err) {
|
||||||
logger.error() << "could not to initialize engine\n" << err.what();
|
logger.error() << "could not to initialize engine\n" << err.what();
|
||||||
}
|
}
|
||||||
|
#ifdef NDEBUG
|
||||||
catch (const std::exception& err) {
|
catch (const std::exception& err) {
|
||||||
logger.error() << "uncaught exception: " << err.what();
|
logger.error() << "uncaught exception: " << err.what();
|
||||||
debug::Logger::flush();
|
debug::Logger::flush();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user