1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

make server a static lib, run it in a separate thread

issues to solve:
- dynamic_cast error 2: One or more of the following type_info's has hidden visibility or is defined in more than one translation unit. They should all have public visibility. 13CPackForLobby, 20LobbyClientConnected, 20LobbyClientConnected.
- error setting socket option: set_option: No buffer space available
This commit is contained in:
Andrey Filipenkov 2021-03-05 19:26:35 +03:00
parent d6f8e4328c
commit 2e18299897
12 changed files with 88 additions and 20 deletions

View File

@ -433,6 +433,7 @@ int main(int argc, char * argv[])
#ifndef VCMI_NO_THREADED_LOAD
// todo ios
#ifdef VCMI_ANDROID // android loads the data quite slowly so we display native progressbar to prevent having only black screen for few seconds
{
CAndroidVMHelper vmHelper;
@ -1136,9 +1137,9 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
logGlobal->warn("Metal unavailable, using OpenGL ES");
createWindow();
}
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); // TODO: isn't setting in Info.plist not enough?
// SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); // TODO: isn't setting in Info.plist not enough?
SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "1");
//SDL_HINT_RETURN_KEY_HIDES_IME
SDL_SetHint(SDL_HINT_RETURN_KEY_HIDES_IME, "1");
logGlobal->info("before SDL_GetWindowSize %dx%d", w, h);
SDL_GetWindowSize(mainWindow, &w, &h);
@ -1315,6 +1316,7 @@ static void handleEvent(SDL_Event & ev)
{
if((ev.type==SDL_QUIT) ||(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
{
// todo ios
#ifdef VCMI_ANDROID
handleQuit(false);
#else

View File

@ -177,7 +177,9 @@ if(WIN32)
target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH)
elseif(APPLE_IOS)
target_link_libraries(vcmiclient PRIVATE
"-framework Foundation -framework UIKit -framework QuartzCore -framework CoreGraphics -framework CoreServices -framework ImageIO" # SDL2_image
vcmiserver
# SDL2_image:
"-framework Foundation -framework UIKit -framework QuartzCore -framework CoreGraphics -framework CoreServices -framework ImageIO"
)
target_sources(vcmiclient PRIVATE ${CMAKE_SOURCE_DIR}/client/LaunchScreen.storyboard)

View File

@ -364,6 +364,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
for(int i = 1; i < 32; i += 2 * speed)
{
movementPxStep(details, i, hp, hero);
// todo ios
#ifndef VCMI_ANDROID
// currently android doesn't seem to be able to handle all these full redraws here, so let's disable it so at least it looks less choppy;
// most likely this is connected with the way that this manual animation+framerate handling is solved

View File

@ -24,7 +24,8 @@
#ifdef VCMI_ANDROID
#include "../lib/CAndroidVMHelper.h"
#elif defined(VCMI_IOS)
//TODO
#include "../server/CVCMIServer.h"
// todo ios
#else
#include "../lib/Interprocess.h"
#endif
@ -184,7 +185,18 @@ void CServerHandler::startLocalServerAndConnect()
envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true);
}
#elif defined(VCMI_IOS)
// TODO
// todo ios: hide keyboard
logNetwork->info("[ios] create server thread");
boost::condition_variable cond;
threadRunLocalServer = std::make_shared<boost::thread>([&cond, this] {
setThreadName("CVCMIServer");
CVCMIServer::create(&cond);
// todo ios copypaste
threadRunLocalServer.reset();
CSH->campaignServerRestartLock.setn(false);
});
// threadRunLocalServer->detach();
logNetwork->info("[ios] detach server thread");
#else
threadRunLocalServer = std::make_shared<boost::thread>(&CServerHandler::threadRunServer, this); //runs server executable;
#endif
@ -202,7 +214,14 @@ void CServerHandler::startLocalServerAndConnect()
logNetwork->info("waiting for server finished...");
androidTestServerReadyFlag = false;
#elif defined(VCMI_IOS)
//TODO
// todo ios
{
boost::mutex m;
boost::unique_lock<boost::mutex> lock{m};
logNetwork->info("[ios] wait for server");
cond.wait(lock);
logNetwork->info("[ios] server ready");
}
#else
if(shm)
shm->sr->waitTillReady();

View File

@ -126,6 +126,7 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
return;
#ifdef VCMI_ANDROID
// todo ios
if(adventureInt->swipeEnabled)
{
if(handleSwipeStateChange((bool)down == true))
@ -151,6 +152,7 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
void CTerrainRect::clickRight(tribool down, bool previousState)
{
#ifdef VCMI_ANDROID
// todo ios
if(adventureInt->swipeEnabled && isSwiping)
return;
#endif
@ -180,6 +182,7 @@ void CTerrainRect::mouseMoved(const SDL_MouseMotionEvent & sEvent)
void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent)
{
#ifdef VCMI_ANDROID
// todo ios
if(sEvent.state == 0) // any "button" is enough on android
#else //!VCMI_ANDROID
if((sEvent.state & SDL_BUTTON_MMASK) == 0) // swipe only works with middle mouse on other platforms
@ -1050,6 +1053,7 @@ void CAdvMapInt::show(SDL_Surface * to)
handleSwipeUpdate();
}
#ifdef VCMI_ANDROID // on android, map-moving mode is exclusive (TODO technically it might work with both enabled; to be checked)
// todo ios
else
#endif // VCMI_ANDROID
{
@ -1452,6 +1456,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{
#ifdef VCMI_ANDROID
// todo ios
if(swipeEnabled)
return;
#endif

View File

@ -5,11 +5,12 @@ ffmpegDir=~/dev/ios/vcmi-ios-deps/mobile-ffmpeg-min-universal
sdlLibsDir=~/dev/ios/vcmi-ios-deps/SDL2-lib
srcDir="../vcmi"
"${2:-cmake}" "$srcDir" -G "$1" \
/Users/Shared/xbmc-depends/x86_64-darwin19.6.0-native/bin/cmake "$srcDir" -G Xcode \
-DENABLE_LAUNCHER=0 \
-Wno-dev \
-DCMAKE_TOOLCHAIN_FILE="$srcDir/ios.toolchain.cmake" \
-DPLATFORM=OS64 \
-DPLATFORM=${1:-OS64} \
-DDEPLOYMENT_TARGET=9.0 \
-DENABLE_BITCODE=0 \
-DCMAKE_BINARY_DIR=$(pwd) \
-DCMAKE_PREFIX_PATH="$boostPrefix;$ffmpegDir;$sdlLibsDir" \

View File

@ -389,7 +389,9 @@ class VCMIDirsIOS final : public VCMIDirsApple
std::vector<bfs::path> dataPaths() const override;
bfs::path libraryPath() const override;
boost::filesystem::path fullLibraryPath(const std::string & desiredFolder, const std::string & baseLibName) const override;
bfs::path binaryPath() const override;
bfs::path serverPath() const override;
bool developmentMode() const override;
};
@ -398,10 +400,13 @@ bfs::path VCMIDirsIOS::userDataPath() const { return {ios_documentsPath()}; }
bfs::path VCMIDirsIOS::userCachePath() const { return {ios_cachesPath()}; }
bfs::path VCMIDirsIOS::userLogsPath() const { return {ios_documentsPath()}; }
std::vector<bfs::path> VCMIDirsIOS::dataPaths() const { return {userDataPath()}; }
std::vector<bfs::path> VCMIDirsIOS::dataPaths() const { return {binaryPath(), userDataPath()}; }
bfs::path VCMIDirsIOS::libraryPath() const { return {ios_frameworksPath()}; }
// todo ios: place AI libs in subdir?
boost::filesystem::path VCMIDirsIOS::fullLibraryPath(const std::string & desiredFolder, const std::string & baseLibName) const { return libraryPath() / libraryName(baseLibName); }
bfs::path VCMIDirsIOS::binaryPath() const { return {ios_bundlePath()}; }
bfs::path VCMIDirsIOS::serverPath() const { return clientPath(); }
bool VCMIDirsIOS::developmentMode() const { return false; }
#elif defined(VCMI_MAC)

View File

@ -154,7 +154,9 @@ std::vector<const ISimpleResourceLoader *> CFilesystemList::getResourcesWithName
std::vector<const ISimpleResourceLoader *> ret;
for (auto & loader : loaders)
boost::range::copy(loader->getResourcesWithName(resourceName), std::back_inserter(ret));
// todo ios
if (loader)
boost::range::copy(loader->getResourcesWithName(resourceName), std::back_inserter(ret));
return ret;
}

View File

@ -33,8 +33,15 @@ using namespace boost::asio::ip;
void CConnection::init()
{
socket->set_option(boost::asio::ip::tcp::no_delay(true));
socket->set_option(boost::asio::socket_base::send_buffer_size(4194304));
socket->set_option(boost::asio::socket_base::receive_buffer_size(4194304));
try
{
socket->set_option(boost::asio::socket_base::send_buffer_size(4194304));
socket->set_option(boost::asio::socket_base::receive_buffer_size(4194304));
}
catch (const boost::system::system_error & e)
{
logNetwork->error("error setting socket option: %s", e.what());
}
enableSmartPointerSerialization();
disableStackSendingByID();

View File

@ -22,7 +22,11 @@ if(ANDROID) # android needs client/server to be libraries, not executables, so w
return()
endif()
add_executable(vcmiserver ${server_SRCS} ${server_HEADERS})
if(APPLE_IOS)
add_library(vcmiserver STATIC ${server_SRCS} ${server_HEADERS})
else()
add_executable(vcmiserver ${server_SRCS} ${server_HEADERS})
endif()
set(server_LIBS vcmi)
if(CMAKE_SYSTEM_NAME MATCHES FreeBSD)

View File

@ -30,7 +30,7 @@
#ifdef VCMI_ANDROID
#include "lib/CAndroidVMHelper.h"
#elif defined(VCMI_IOS)
//TODO
// todo ios
#else
#include "../lib/Interprocess.h"
#endif
@ -114,8 +114,8 @@ public:
}
};
std::string NAME_AFFIX = "server";
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')';
std::string SERVER_NAME_AFFIX = "server";
std::string SERVER_NAME = GameConstants::VCMI_VERSION + std::string(" (") + SERVER_NAME_AFFIX + ')';
CVCMIServer::CVCMIServer(boost::program_options::variables_map & opts)
: port(3030), io(std::make_shared<boost::asio::io_service>()), state(EServerState::LOBBY), cmdLineOptions(opts), currentClientId(1), currentPlayerId(1), restartGameplay(false)
@ -293,7 +293,7 @@ void CVCMIServer::connectionAccepted(const boost::system::error_code & ec)
try
{
logNetwork->info("We got a new connection! :)");
auto c = std::make_shared<CConnection>(upcomingConnection, NAME, uuid);
auto c = std::make_shared<CConnection>(upcomingConnection, SERVER_NAME, uuid);
upcomingConnection.reset();
connections.insert(c);
c->handler = std::make_shared<boost::thread>(&CVCMIServer::threadHandleClient, this, c);
@ -901,6 +901,9 @@ static void handleCommandOptions(int argc, char * argv[], boost::program_options
}
}
#ifdef VCMI_IOS
#define main server_main
#endif
int main(int argc, char * argv[])
{
#if !defined(VCMI_ANDROID) && !defined(VCMI_IOS)
@ -913,12 +916,19 @@ int main(int argc, char * argv[])
signal(SIGSEGV, handleLinuxSignal);
#endif
// todo ios: double console log
console = new CConsoleHandler();
CBasicLogConfigurator logConfig(VCMIDirs::get().userLogsPath() / "VCMI_Server_log.txt", console);
logConfig.configureDefault();
logGlobal->info(NAME);
logGlobal->info(SERVER_NAME);
boost::program_options::variables_map opts;
boost::program_options::variables_map opts;
#ifdef VCMI_IOS
argc = 1;
boost::condition_variable * cond = reinterpret_cast<boost::condition_variable *>(argv[1]);
cond->notify_one();
//#endif
#else
handleCommandOptions(argc, argv, opts);
preinitDLL(console);
settings.init();
@ -926,6 +936,8 @@ int main(int argc, char * argv[])
loadDLLClasses();
srand((ui32)time(nullptr));
//#ifdef VCMI_IOS
#endif
try
{
boost::asio::io_service io_service;
@ -965,11 +977,17 @@ int main(int argc, char * argv[])
return 0;
}
// TODO iOS
#ifdef VCMI_ANDROID
void CVCMIServer::create()
{
const char * foo[1] = {"android-server"};
main(1, const_cast<char **>(foo));
}
#elif defined(VCMI_IOS)
void CVCMIServer::create(boost::condition_variable * cond)
{
const auto executablePath = VCMIDirs::get().serverPath();
void *argv[] = {const_cast<char *>(executablePath.c_str()), cond};
main(2, reinterpret_cast<char **>(argv));
}
#endif

View File

@ -103,5 +103,7 @@ public:
#ifdef VCMI_ANDROID
static void create();
#elif defined(VCMI_IOS)
static void create(boost::condition_variable * cond);
#endif
};