mirror of
https://github.com/tnodir/fort
synced 2024-11-15 08:15:10 +00:00
UI: IocContainer is non-intrusive.
This commit is contained in:
parent
c28e626dbd
commit
e0748c4ee9
@ -5,16 +5,16 @@
|
||||
#include <googletest.h>
|
||||
|
||||
#include <util/ioc/ioccontainer.h>
|
||||
#include <util/ioc/iocobject.h>
|
||||
#include <util/ioc/iocservice.h>
|
||||
|
||||
namespace IocTest {
|
||||
|
||||
class A : public IocObject
|
||||
class A : public IocService
|
||||
{
|
||||
public:
|
||||
void setUp() override
|
||||
{
|
||||
IocObject::setUp();
|
||||
IocService::setUp();
|
||||
setIsA(true);
|
||||
}
|
||||
|
||||
@ -37,12 +37,12 @@ public:
|
||||
MOCK_METHOD1(setIsA, void(bool v));
|
||||
};
|
||||
|
||||
class B : public IocObject
|
||||
class B : public IocService
|
||||
{
|
||||
public:
|
||||
void setUp() override
|
||||
{
|
||||
IocObject::setUp();
|
||||
IocService::setUp();
|
||||
IoC()->setUpDependency<A>();
|
||||
}
|
||||
};
|
||||
@ -82,10 +82,10 @@ TEST_F(IocContainerTest, insert)
|
||||
IocContainer container;
|
||||
|
||||
auto a2 = new IocTest::A2();
|
||||
container.insert<IocTest::A>(a2);
|
||||
container.setService<IocTest::A>(a2);
|
||||
|
||||
IocTest::B b;
|
||||
container.insert<IocTest::B>(b);
|
||||
container.setService<IocTest::B>(b);
|
||||
|
||||
ASSERT_EQ(container.resolve<IocTest::A>(), a2);
|
||||
ASSERT_TRUE(container.pinToThread());
|
||||
@ -97,7 +97,7 @@ TEST_F(IocContainerTest, setUp)
|
||||
IocContainer container;
|
||||
|
||||
auto a2 = new IocTest::A2();
|
||||
container.insert<IocTest::A>(a2);
|
||||
container.setService<IocTest::A>(a2);
|
||||
|
||||
ASSERT_FALSE(a2->isA());
|
||||
container.setUpAll();
|
||||
@ -115,10 +115,10 @@ TEST_F(IocContainerTest, mockSetUp)
|
||||
ASSERT_TRUE(container.pinToThread());
|
||||
|
||||
NiceMock<IocTest::MockA> mockA;
|
||||
container.insert<IocTest::A>(&mockA);
|
||||
container.setService<IocTest::A>(&mockA);
|
||||
|
||||
auto b = new IocTest::B();
|
||||
container.insert<IocTest::B>(b);
|
||||
container.setService<IocTest::B>(b);
|
||||
|
||||
EXPECT_CALL(mockA, setIsA(true)).Times(1);
|
||||
container.setUpAll();
|
||||
@ -127,7 +127,7 @@ TEST_F(IocContainerTest, mockSetUp)
|
||||
EXPECT_CALL(mockA, tearDown()).Times(1);
|
||||
container.tearDownAll();
|
||||
|
||||
const int containerSize = container.objects().size();
|
||||
container.insert<IocTest::A>(nullptr);
|
||||
ASSERT_EQ(container.objects().size(), containerSize);
|
||||
const int containerSize = container.size();
|
||||
container.remove<IocTest::A>();
|
||||
ASSERT_EQ(container.size(), containerSize);
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ HEADERS += \
|
||||
util/ini/mapsettings.h \
|
||||
util/ini/settings.h \
|
||||
util/ioc/ioccontainer.h \
|
||||
util/ioc/iocobject.h \
|
||||
util/ioc/iocservice.h \
|
||||
util/json/jsonutil.h \
|
||||
util/json/mapwrapper.h \
|
||||
util/logger.h \
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <QVariant>
|
||||
|
||||
#include "../util/classhelpers.h"
|
||||
#include "../util/ioc/iocobject.h"
|
||||
#include "control.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QLocalServer)
|
||||
@ -17,7 +16,7 @@ class FortManager;
|
||||
class FortSettings;
|
||||
class RpcManager;
|
||||
|
||||
class ControlManager : public QObject, public IocObject
|
||||
class ControlManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "util/classhelpers.h"
|
||||
#include "util/ioc/iocobject.h"
|
||||
|
||||
class AppInfoCache;
|
||||
class AppInfoManager;
|
||||
@ -34,7 +33,7 @@ class UserSettings;
|
||||
class ZoneListModel;
|
||||
class ZonesWindow;
|
||||
|
||||
class FortManager : public QObject, public IocObject
|
||||
class FortManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -2,12 +2,11 @@
|
||||
#define FORTSETTINGS_H
|
||||
|
||||
#include "util/ini/settings.h"
|
||||
#include "util/ioc/iocobject.h"
|
||||
|
||||
class EnvManager;
|
||||
class FirewallConf;
|
||||
|
||||
class FortSettings : public Settings, public IocObject
|
||||
class FortSettings : public Settings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -4,9 +4,7 @@
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
|
||||
#include "ioc/iocobject.h"
|
||||
|
||||
class EnvManager : public QObject, public IocObject
|
||||
class EnvManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <qt_windows.h>
|
||||
|
||||
#include "iocobject.h"
|
||||
#include "iocservice.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -20,10 +20,8 @@ IocContainer::~IocContainer()
|
||||
{
|
||||
tearDownAll();
|
||||
|
||||
for (IocObject *obj : qAsConst(m_objects)) {
|
||||
if (obj && obj->autoDelete()) {
|
||||
delete obj;
|
||||
}
|
||||
for (int i = 0; i < m_size; ++i) {
|
||||
autoDelete(i);
|
||||
}
|
||||
|
||||
if (g_tlsIndex != -1) {
|
||||
@ -32,18 +30,23 @@ IocContainer::~IocContainer()
|
||||
}
|
||||
}
|
||||
|
||||
void IocContainer::insertObject(int typeId, IocObject *obj, bool autoDelete)
|
||||
void IocContainer::setObject(int typeId, IocObject *obj, quint8 flags)
|
||||
{
|
||||
const int newSize = typeId + 1;
|
||||
if (newSize > m_objects.size()) {
|
||||
if (newSize > m_size) {
|
||||
if (newSize >= IOC_MAX_SIZE) {
|
||||
qCritical() << "IoC Container size error" << IOC_MAX_SIZE << newSize;
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
m_size = newSize;
|
||||
m_objects.resize(newSize);
|
||||
m_objectFlags.resize(newSize);
|
||||
}
|
||||
|
||||
m_objects[typeId] = obj;
|
||||
|
||||
if (obj) {
|
||||
obj->setAutoDelete(autoDelete);
|
||||
}
|
||||
Q_ASSERT(obj || flags == 0);
|
||||
m_objectFlags[typeId] = flags;
|
||||
}
|
||||
|
||||
IocObject *IocContainer::resolveObject(int typeId) const
|
||||
@ -53,29 +56,52 @@ IocObject *IocContainer::resolveObject(int typeId) const
|
||||
return obj;
|
||||
}
|
||||
|
||||
IocService *IocContainer::resolveService(int typeId) const
|
||||
{
|
||||
return static_cast<IocService *>(resolveObject(typeId));
|
||||
}
|
||||
|
||||
void IocContainer::setUpAll()
|
||||
{
|
||||
for (IocObject *obj : qAsConst(m_objects)) {
|
||||
if (obj) {
|
||||
setUp(obj);
|
||||
}
|
||||
for (int i = 0; i < m_size; ++i) {
|
||||
setUp(i);
|
||||
}
|
||||
}
|
||||
|
||||
void IocContainer::tearDownAll()
|
||||
{
|
||||
for (IocObject *obj : qAsConst(m_objects)) {
|
||||
if (obj) {
|
||||
obj->tearDown();
|
||||
}
|
||||
for (int i = 0; i < m_size; ++i) {
|
||||
tearDown(i);
|
||||
}
|
||||
}
|
||||
|
||||
void IocContainer::setUp(IocObject *obj)
|
||||
void IocContainer::setUp(int typeId)
|
||||
{
|
||||
if (!obj->wasSetUp()) {
|
||||
obj->setUp();
|
||||
}
|
||||
const quint8 flags = m_objectFlags[typeId];
|
||||
if ((flags & (IsService | WasSetUp)) != IsService)
|
||||
return;
|
||||
|
||||
m_objectFlags[typeId] = (flags | WasSetUp);
|
||||
|
||||
resolveService(typeId)->setUp();
|
||||
}
|
||||
|
||||
void IocContainer::tearDown(int typeId)
|
||||
{
|
||||
const quint8 flags = m_objectFlags[typeId];
|
||||
if (!(flags & IsService))
|
||||
return;
|
||||
|
||||
resolveService(typeId)->tearDown();
|
||||
}
|
||||
|
||||
void IocContainer::autoDelete(int typeId)
|
||||
{
|
||||
const quint8 flags = m_objectFlags[typeId];
|
||||
if ((flags & (AutoDelete | IsService)) != (AutoDelete | IsService))
|
||||
return;
|
||||
|
||||
delete resolveService(typeId);
|
||||
}
|
||||
|
||||
bool IocContainer::pinToThread()
|
||||
|
@ -2,40 +2,56 @@
|
||||
#define IOCCONTAINER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QVarLengthArray>
|
||||
|
||||
class IocObject;
|
||||
class IocService;
|
||||
|
||||
using IocObject = void;
|
||||
|
||||
constexpr int IOC_MAX_SIZE = 32;
|
||||
|
||||
class IocContainer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum IocFlag : quint8 { AutoDelete = 0x01, IsService = 0x02, WasSetUp = 0x04 };
|
||||
|
||||
explicit IocContainer(QObject *parent = nullptr);
|
||||
~IocContainer() override;
|
||||
|
||||
const QVector<IocObject *> &objects() const { return m_objects; }
|
||||
const int size() const { return m_size; }
|
||||
|
||||
template<class T>
|
||||
void put(T *obj)
|
||||
void set(T &obj)
|
||||
{
|
||||
QObject *qObj = qobject_cast<QObject *>(obj);
|
||||
Q_ASSERT(qObj);
|
||||
qObj->setParent(this);
|
||||
|
||||
insert(obj);
|
||||
setObject(getTypeId<T>(), &obj);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void insert(T *obj)
|
||||
void set(T *obj)
|
||||
{
|
||||
insertObject(getTypeId<T>(), obj);
|
||||
setObject(getTypeId<T>(), obj, AutoDelete);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void insert(T &obj)
|
||||
void remove()
|
||||
{
|
||||
insertObject(getTypeId<T>(), &obj, false);
|
||||
setObject(getTypeId<T>(), nullptr);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void setService(T &obj)
|
||||
{
|
||||
Q_ASSERT(static_cast<IocService *>(&obj));
|
||||
setObject(getTypeId<T>(), &obj, IsService);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void setService(T *obj)
|
||||
{
|
||||
Q_ASSERT(static_cast<IocService *>(obj));
|
||||
setObject(getTypeId<T>(), obj, AutoDelete | IsService);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@ -50,11 +66,9 @@ public:
|
||||
template<class T>
|
||||
void setUpDependency()
|
||||
{
|
||||
setUp(resolve<T>());
|
||||
setUp(getTypeId<T>());
|
||||
}
|
||||
|
||||
void setUp(IocObject *obj);
|
||||
|
||||
bool pinToThread();
|
||||
|
||||
static IocContainer *getPinned();
|
||||
@ -62,18 +76,26 @@ public:
|
||||
template<class T>
|
||||
static int getTypeId()
|
||||
{
|
||||
static int typeId = getNextTypeId();
|
||||
static const int typeId = getNextTypeId();
|
||||
return typeId;
|
||||
}
|
||||
|
||||
private:
|
||||
void insertObject(int typeId, IocObject *obj, bool autoDelete = true);
|
||||
void setObject(int typeId, IocObject *obj, quint8 flags = 0);
|
||||
|
||||
IocObject *resolveObject(int typeId) const;
|
||||
IocService *resolveService(int typeId) const;
|
||||
|
||||
void setUp(int typeId);
|
||||
void tearDown(int typeId);
|
||||
void autoDelete(int typeId);
|
||||
|
||||
static int getNextTypeId();
|
||||
|
||||
private:
|
||||
QVector<IocObject *> m_objects;
|
||||
int m_size = 0;
|
||||
QVarLengthArray<IocObject *, IOC_MAX_SIZE> m_objects;
|
||||
QVarLengthArray<quint8, IOC_MAX_SIZE> m_objectFlags;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
@ -1,24 +0,0 @@
|
||||
#ifndef IOCOBJECT_H
|
||||
#define IOCOBJECT_H
|
||||
|
||||
class IocObject
|
||||
{
|
||||
public:
|
||||
explicit IocObject() : m_autoDelete(true), m_wasSetUp(false) { }
|
||||
virtual ~IocObject() = default;
|
||||
|
||||
virtual void setUp() { setWasSetUp(true); }
|
||||
virtual void tearDown() { }
|
||||
|
||||
bool autoDelete() const { return m_autoDelete; }
|
||||
void setAutoDelete(bool v) { m_autoDelete = v; }
|
||||
|
||||
bool wasSetUp() const { return m_wasSetUp; }
|
||||
void setWasSetUp(bool v) { m_wasSetUp = v; }
|
||||
|
||||
private:
|
||||
bool m_autoDelete : 1;
|
||||
bool m_wasSetUp : 1;
|
||||
};
|
||||
|
||||
#endif // IOCOBJECT_H
|
14
src/ui/util/ioc/iocservice.h
Normal file
14
src/ui/util/ioc/iocservice.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef IOCSERVICE_H
|
||||
#define IOCSERVICE_H
|
||||
|
||||
class IocService
|
||||
{
|
||||
public:
|
||||
explicit IocService() = default;
|
||||
virtual ~IocService() = default;
|
||||
|
||||
virtual void setUp() { }
|
||||
virtual void tearDown() { }
|
||||
};
|
||||
|
||||
#endif // IOCSERVICE_H
|
@ -121,10 +121,10 @@ int main(int argc, char *argv[])
|
||||
// Setup IoC Container
|
||||
IocContainer ioc;
|
||||
ioc.pinToThread();
|
||||
ioc.insert<FortSettings>(settings);
|
||||
ioc.insert<EnvManager>(envManager);
|
||||
ioc.insert<ControlManager>(controlManager);
|
||||
ioc.insert<FortManager>(fortManager);
|
||||
ioc.set<FortSettings>(settings);
|
||||
ioc.set<EnvManager>(envManager);
|
||||
ioc.set<ControlManager>(controlManager);
|
||||
ioc.set<FortManager>(fortManager);
|
||||
|
||||
// Check running instance
|
||||
if (!fortManager.checkRunningInstance())
|
||||
|
Loading…
Reference in New Issue
Block a user