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

Removed asynchronous calls from exchange window

This commit is contained in:
Ivan Savenko 2023-07-18 17:29:17 +03:00
parent bb17cc13b1
commit c7d88271a9
2 changed files with 32 additions and 93 deletions

View File

@ -60,9 +60,8 @@ namespace boost { class thread; }
template<typename T> template<typename T>
class ThreadSafeVector class ThreadSafeVector
{ {
using TVector = std::vector<T>;
using TLock = boost::unique_lock<boost::mutex>; using TLock = boost::unique_lock<boost::mutex>;
TVector items; std::vector<T> items;
boost::mutex mx; boost::mutex mx;
boost::condition_variable cond; boost::condition_variable cond;
@ -81,28 +80,16 @@ public:
cond.notify_all(); cond.notify_all();
} }
// //to access list, caller must present a lock used to lock mx
// TVector &getList(TLock &lockedLock)
// {
// assert(lockedLock.owns_lock() && lockedLock.mutex() == &mx);
// return items;
// }
TLock getLock()
{
return TLock(mx);
}
void waitWhileContains(const T & item) void waitWhileContains(const T & item)
{ {
auto lock = getLock(); TLock lock(mx);
while(vstd::contains(items, item)) while(vstd::contains(items, item))
cond.wait(lock); cond.wait(lock);
} }
bool tryRemovingElement(const T & item) //returns false if element was not present bool tryRemovingElement(const T & item) //returns false if element was not present
{ {
auto lock = getLock(); TLock lock(mx);
auto itr = vstd::find(items, item); auto itr = vstd::find(items, item);
if(itr == items.end()) //not in container if(itr == items.end()) //not in container
{ {

View File

@ -621,51 +621,6 @@ static bool isQuickExchangeLayoutAvailable()
return CResourceHandler::get()->existsResource(ResourceID(std::string("SPRITES/") + QUICK_EXCHANGE_BG, EResType::IMAGE)); return CResourceHandler::get()->existsResource(ResourceID(std::string("SPRITES/") + QUICK_EXCHANGE_BG, EResType::IMAGE));
} }
// Runs a task asynchronously with gamestate locking and waitTillRealize set to true
class GsThread
{
private:
std::function<void()> action;
std::shared_ptr<CCallback> cb;
public:
static void run(std::function<void()> action)
{
std::shared_ptr<GsThread> instance(new GsThread(action));
boost::thread(std::bind(&GsThread::staticRun, instance));
}
private:
GsThread(std::function<void()> action)
:action(action), cb(LOCPLINT->cb)
{
}
static void staticRun(std::shared_ptr<GsThread> instance)
{
instance->run();
}
void run()
{
boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex);
auto originalWaitTillRealize = cb->waitTillRealize;
auto originalUnlockGsWhenWating = cb->unlockGsWhenWaiting;
cb->waitTillRealize = true;
cb->unlockGsWhenWaiting = true;
action();
cb->waitTillRealize = originalWaitTillRealize;
cb->unlockGsWhenWaiting = originalUnlockGsWhenWating;
}
};
CExchangeController::CExchangeController(CExchangeWindow * view, ObjectInstanceID hero1, ObjectInstanceID hero2) CExchangeController::CExchangeController(CExchangeWindow * view, ObjectInstanceID hero1, ObjectInstanceID hero2)
:left(LOCPLINT->cb->getHero(hero1)), right(LOCPLINT->cb->getHero(hero2)), cb(LOCPLINT->cb), view(view) :left(LOCPLINT->cb->getHero(hero1)), right(LOCPLINT->cb->getHero(hero2)), cb(LOCPLINT->cb), view(view)
{ {
@ -697,10 +652,7 @@ std::function<void()> CExchangeController::onSwapArtifacts()
{ {
return [&]() return [&]()
{ {
GsThread::run([=] cb->bulkMoveArtifacts(left->id, right->id, true);
{
cb->bulkMoveArtifacts(left->id, right->id, true);
});
}; };
} }
@ -725,39 +677,42 @@ std::function<void()> CExchangeController::onSwapArmy()
{ {
return [&]() return [&]()
{ {
GsThread::run([=] if(left->tempOwner != cb->getMyColor()
|| right->tempOwner != cb->getMyColor())
{ {
if(left->tempOwner != cb->getMyColor() return;
|| right->tempOwner != cb->getMyColor()) }
{
return;
}
auto leftSlots = getStacks(left); auto leftSlots = getStacks(left);
auto rightSlots = getStacks(right); auto rightSlots = getStacks(right);
auto i = leftSlots.begin(), j = rightSlots.begin(); auto i = leftSlots.begin(), j = rightSlots.begin();
for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++) for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++)
{ {
cb->swapCreatures(left, right, i->first, j->first); cb->swapCreatures(left, right, i->first, j->first);
} }
if(i != leftSlots.end()) if(i != leftSlots.end())
{
auto freeSlots = right->getFreeSlots();
auto slot = freeSlots.begin();
for(; i != leftSlots.end() && slot != freeSlots.end(); i++, slot++)
{ {
for(; i != leftSlots.end(); i++) cb->swapCreatures(left, right, i->first, *slot);
{
cb->swapCreatures(left, right, i->first, right->getFreeSlot());
}
} }
else if(j != rightSlots.end()) }
else if(j != rightSlots.end())
{
auto freeSlots = left->getFreeSlots();
auto slot = freeSlots.begin();
for(; j != rightSlots.end() && slot != freeSlots.end(); j++, slot++)
{ {
for(; j != rightSlots.end(); j++) cb->swapCreatures(left, right, *slot, j->first);
{
cb->swapCreatures(left, right, left->getFreeSlot(), j->first);
}
} }
}); }
}; };
} }
@ -854,10 +809,7 @@ void CExchangeController::moveArtifacts(bool leftToRight)
return; return;
} }
GsThread::run([=] cb->bulkMoveArtifacts(source->id, target->id, false);
{
cb->bulkMoveArtifacts(source->id, target->id, false);
});
} }
void CExchangeController::moveArtifact( void CExchangeController::moveArtifact(