[ios][mac] Added implementations for Platform::RunOnGuiThread and Platform::RunAsync

@see #486
This commit is contained in:
Alex Zolotarev 2011-12-28 16:13:14 +03:00 committed by Alex Zolotarev
parent 8bbae498e4
commit 8e01578207
15 changed files with 96 additions and 189 deletions

View file

@ -25,7 +25,6 @@ LOCAL_HEADER_FILES := \
nv_event/scoped_profiler.hpp
LOCAL_SRC_FILES := \
com/mapswithme/core/concurrent_runner.cpp \
com/mapswithme/core/jni_helper.cpp \
com/mapswithme/core/jni_string.cpp \
com/mapswithme/core/logging.cpp \

View file

@ -1,21 +0,0 @@
#include "../../../../../platform/concurrent_runner.hpp"
namespace threads
{
ConcurrentRunner::ConcurrentRunner()
{
}
ConcurrentRunner::~ConcurrentRunner()
{
}
void ConcurrentRunner::Run(RunnerFuncT const & f) const
{
}
void ConcurrentRunner::Join()
{
}
}

View file

@ -1,23 +0,0 @@
#pragma once
#include "../base/runner.hpp"
namespace threads
{
/// @note All current implementations use one shared system pool
class ConcurrentRunner : public IRunner
{
class Impl;
Impl * m_pImpl;
public:
ConcurrentRunner();
virtual ~ConcurrentRunner();
virtual void Run(RunnerFuncT const & f) const;
protected:
virtual void Join();
};
}

View file

@ -1,67 +0,0 @@
#include "concurrent_runner.hpp"
#include "../base/assert.hpp"
#include "../base/macros.hpp"
#include "../base/logging.hpp"
#include "../std/scoped_ptr.hpp"
#include <dispatch/dispatch.h>
namespace threads
{
class ConcurrentRunner::Impl
{
public:
dispatch_group_t m_group;
Impl()
{
m_group = dispatch_group_create();
}
~Impl()
{
dispatch_release(m_group);
}
};
ConcurrentRunner::ConcurrentRunner() : m_pImpl(new ConcurrentRunner::Impl)
{
}
ConcurrentRunner::~ConcurrentRunner()
{
delete m_pImpl;
}
// work-around for runtime boost exception, see
// http://stackoverflow.com/questions/5438613/why-cant-i-use-a-boostfunction-in-an-objective-c-block
struct BoostExceptionFixer
{
RunnerFuncT m_f;
BoostExceptionFixer(RunnerFuncT const & f) : m_f(f) {}
void operator()() const
{
scoped_ptr<BoostExceptionFixer> scopedThis;
UNUSED_VALUE(scopedThis);
IRunner::CallAndCatchAll(m_f);
}
};
void ConcurrentRunner::Run(RunnerFuncT const & f) const
{
dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
BoostExceptionFixer * tmp = new BoostExceptionFixer(f);
dispatch_group_async(m_pImpl->m_group, globalQ, ^{
(*tmp)();
});
}
void ConcurrentRunner::Join()
{
dispatch_group_wait(m_pImpl->m_group, DISPATCH_TIME_FOREVER);
}
}

View file

@ -72,8 +72,15 @@ public:
/// @name Functions for concurrent tasks.
//@{
typedef function<void()> TFunctor;
inline void RunInGuiThread(TFunctor const & fn) { fn(); }
inline void RunAsync(TFunctor const & fn) { fn(); }
void RunOnGuiThread(TFunctor const & fn);
enum Priority
{
EPriorityBackground,
EPriorityLow,
EPriorityDefault,
EPriorityHigh
};
void RunAsync(TFunctor const & fn, Priority p = EPriorityDefault);
//@}
int CpuCores() const;

View file

@ -15,7 +15,6 @@ include($$ROOT_DIR/common.pri)
SOURCES += platform_qt.cpp \
wifi_location_service.cpp \
qt_concurrent_runner.cpp \
location_service.cpp
HEADERS += wifi_info.hpp \
location_service.hpp
@ -38,7 +37,6 @@ include($$ROOT_DIR/common.pri)
}
} else:iphone* {
OBJECTIVE_SOURCES += ios_video_timer.mm \
ios_concurrent_runner.mm \
platform_ios.mm
} else:android* {
SOURCES += platform_android.cpp \
@ -55,7 +53,6 @@ macx*|iphone* {
HEADERS += \
platform.hpp \
location.hpp \
concurrent_runner.hpp \
preferred_languages.hpp \
settings.hpp \
video_timer.hpp \

View file

@ -167,3 +167,15 @@ bool Platform::IsFeatureSupported(string const & feature) const
// @TODO add Search feature support
return false;
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
// @TODO
fn();
}
void Platform::RunAsync(TFunctor const & fn, Priority p)
{
// @TODO
fn();
}

View file

@ -273,6 +273,31 @@ bool Platform::IsFeatureSupported(string const & feature) const
return false;
}
static void PerformImpl(void * obj)
{
Platform::TFunctor * f = reinterpret_cast<Platform::TFunctor *>(obj);
(*f)();
delete f;
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
dispatch_async_f(dispatch_get_main_queue(), new TFunctor(fn), &PerformImpl);
}
void Platform::RunAsync(TFunctor const & fn, Priority p)
{
int priority = DISPATCH_QUEUE_PRIORITY_DEFAULT;
switch (p)
{
case EPriorityBackground: priority = DISPATCH_QUEUE_PRIORITY_BACKGROUND; break;
case EPriorityDefault: priority = DISPATCH_QUEUE_PRIORITY_DEFAULT; break;
case EPriorityHigh: priority = DISPATCH_QUEUE_PRIORITY_HIGH; break;
case EPriorityLow: priority = DISPATCH_QUEUE_PRIORITY_LOW; break;
}
dispatch_async_f(dispatch_get_global_queue(priority, 0), new TFunctor(fn), &PerformImpl);
}
////////////////////////////////////////////////////////////////////////
extern "C" Platform & GetPlatform()
{

View file

@ -68,3 +68,15 @@ string Platform::UniqueClientId() const
{
return "@TODO";
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
// @TODO
fn();
}
void Platform::RunAsync(TFunctor const & fn, Priority p)
{
// @TODO
fn();
}

View file

@ -102,3 +102,28 @@ string Platform::UniqueClientId() const
// and use base64 encoding
return base64::encode(xoredHash);
}
static void PerformImpl(void * obj)
{
Platform::TFunctor * f = reinterpret_cast<Platform::TFunctor *>(obj);
(*f)();
delete f;
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
dispatch_async_f(dispatch_get_main_queue(), new TFunctor(fn), &PerformImpl);
}
void Platform::RunAsync(TFunctor const & fn, Priority p)
{
int priority = DISPATCH_QUEUE_PRIORITY_DEFAULT;
switch (p)
{
case EPriorityBackground: priority = DISPATCH_QUEUE_PRIORITY_BACKGROUND; break;
case EPriorityDefault: priority = DISPATCH_QUEUE_PRIORITY_DEFAULT; break;
case EPriorityHigh: priority = DISPATCH_QUEUE_PRIORITY_HIGH; break;
case EPriorityLow: priority = DISPATCH_QUEUE_PRIORITY_LOW; break;
}
dispatch_async_f(dispatch_get_global_queue(priority, 0), new TFunctor(fn), &PerformImpl);
}

View file

@ -1,41 +0,0 @@
#include "../../testing/testing.hpp"
#include "../concurrent_runner.hpp"
#include "../platform.hpp"
#include "../../base/logging.hpp"
#include "../../base/mutex.hpp"
#include "../../std/bind.hpp"
namespace
{
class ConcurrentRunnerForTest : public threads::ConcurrentRunner
{
public:
using threads::ConcurrentRunner::Join;
};
}
int globalCounter = 0;
threads::Mutex m;
void f()
{
threads::MutexGuard g(m);
++globalCounter;
}
static const int MAX_THREADS = 20;
UNIT_TEST(ConcurrentRunnerSmoke)
{
ConcurrentRunnerForTest r;
for (int i = 0; i < MAX_THREADS; ++i)
r.Run(&f);
r.Join();
TEST_EQUAL(globalCounter, MAX_THREADS, ());
}

View file

@ -30,7 +30,6 @@ SOURCES += \
../../testing/testingmain.cpp \
platform_test.cpp \
jansson_test.cpp \
concurrent_runner_test.cpp \
language_test.cpp \
downloader_test.cpp \
video_timer_test.cpp \

View file

@ -100,3 +100,15 @@ string Platform::UniqueClientId() const
{
return "@TODO";
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
// @TODO
fn();
}
void Platform::RunAsync(TFunctor const & fn, Priority p)
{
// @TODO
fn();
}

View file

@ -1,29 +0,0 @@
#include "concurrent_runner.hpp"
#include "../std/bind.hpp"
#include <QtCore/QtConcurrentRun>
#include <QtCore/QThreadPool>
namespace threads
{
ConcurrentRunner::ConcurrentRunner()
{
}
ConcurrentRunner::~ConcurrentRunner()
{
}
void ConcurrentRunner::Run(RunnerFuncT const & f) const
{
QtConcurrent::run(bind(&IRunner::CallAndCatchAll, f));
}
void ConcurrentRunner::Join()
{
QThreadPool::globalInstance()->waitForDone();
}
} // namespace threads

View file

@ -369,7 +369,7 @@ namespace storage
{
if (indexer::BuildSearchIndexFromDatFile(fName))
{
GetPlatform().RunInGuiThread(bind(&Storage::UpdateAfterSearchIndex, this, cref(fName)));
GetPlatform().RunOnGuiThread(bind(&Storage::UpdateAfterSearchIndex, this, cref(fName)));
}
else
{