initial player stuff
This commit is contained in:
parent
4b60ece582
commit
00f26c431e
@ -23,6 +23,7 @@ set(SOURCES
|
||||
)
|
||||
|
||||
add_executable(corax ${HEADERS} ${SOURCES})
|
||||
add_subdirectory(models)
|
||||
|
||||
target_link_libraries(corax Qt5::Core)
|
||||
target_link_libraries(corax Qt5::Network)
|
||||
@ -31,10 +32,10 @@ target_link_libraries(corax wSocket)
|
||||
target_link_libraries(corax wDispatcher)
|
||||
target_link_libraries(corax utils)
|
||||
target_link_libraries(corax wModel)
|
||||
target_link_libraries(corax wController)
|
||||
target_link_libraries(corax wServerUtils)
|
||||
target_link_libraries(corax wDatabase)
|
||||
target_link_libraries(corax tag)
|
||||
target_link_libraries(corax tools)
|
||||
target_link_libraries(corax coraxModels)
|
||||
target_link_libraries(corax wServerUtils)
|
||||
|
||||
install(TARGETS corax RUNTIME DESTINATION bin)
|
||||
|
@ -90,11 +90,11 @@ void Corax::start()
|
||||
server->listen(8080);
|
||||
|
||||
cout << "Registering models..." << endl;
|
||||
attributes->registerModel(dispatcher, server);
|
||||
commands->registerModel(dispatcher, server);
|
||||
attributes->getRegistered(connector);
|
||||
commands->getRegistered(connector);
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
beg->second->registerModel(dispatcher, server);
|
||||
beg->second->getRegistered(connector);
|
||||
}
|
||||
|
||||
cout << "Opening caches..." << endl;
|
||||
@ -115,11 +115,11 @@ void Corax::stop()
|
||||
std::map<W::String, ResourceCache*>::iterator end = caches.end();
|
||||
|
||||
cout << "Stopping corax..." << endl;
|
||||
commands->unregisterModel();
|
||||
attributes->unregisterModel();
|
||||
commands->getUnregistered();
|
||||
attributes->getUnregistered();
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
beg->second->unregisterModel();
|
||||
beg->second->getUnregistered();
|
||||
}
|
||||
|
||||
server->stop();
|
||||
@ -169,10 +169,10 @@ void Corax::h_parseDirectory(const W::Event& ev)
|
||||
if (itr != parsers.end()) {
|
||||
cout << "directory " << path.toString() << " is already being parsed" << endl;
|
||||
} else {
|
||||
const W::Socket& socket = connector->getNodeSocket(W::String(u"Perturabo"));
|
||||
const W::Socket* socket = connector->getNodeSocket(W::String(u"Perturabo"));
|
||||
ResourceCache* music = caches.at(W::String(u"music"));
|
||||
ResourceCache* images = caches.at(W::String(u"images"));
|
||||
Parser* parser = new Parser(&socket, dispatcher, music, images);
|
||||
Parser* parser = new Parser(socket, dispatcher, music, images);
|
||||
parsers.insert(std::make_pair(path, parser));
|
||||
|
||||
connect(parser, SIGNAL(serviceMessage(const QString&)), SLOT(onModelServiceMessage(const QString&)));
|
||||
|
21
corax/models/CMakeLists.txt
Normal file
21
corax/models/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(coraxModels)
|
||||
|
||||
find_package(Qt5Core REQUIRED)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
set(HEADERS
|
||||
player.h
|
||||
proxysong.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
player.cpp
|
||||
proxysong.cpp
|
||||
)
|
||||
|
||||
add_library(coraxModels STATIC ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(coraxModels wModel)
|
121
corax/models/player.cpp
Normal file
121
corax/models/player.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include "player.h"
|
||||
|
||||
M::Player::Player(const W::Address& address, QObject* parent):
|
||||
M::Model(address, parent),
|
||||
controls(),
|
||||
views(),
|
||||
playPauseBtn(new M::Button(address + W::Address{u"play"})),
|
||||
_queueView(new M::List(address + W::Address{u"queueView"})),
|
||||
_queue(),
|
||||
current(0)
|
||||
{
|
||||
W::Handler* get = W::Handler::create(address + W::Address({u"get"}), this, &M::Player::_h_get);
|
||||
W::Handler* hqueue = W::Handler::create(address + W::Address({u"queue"}), this, &M::Player::_h_queue);
|
||||
addHandler(get);
|
||||
addHandler(hqueue);
|
||||
|
||||
playPauseBtn->setLabel(W::String(u"play"));
|
||||
playPauseBtn->setEnabled(false);
|
||||
connect(playPauseBtn, SIGNAL(activated()), this, SLOT(onPlayPauseBtn()));
|
||||
|
||||
addModel(playPauseBtn);
|
||||
addModel(_queueView);
|
||||
|
||||
controls.insert(std::make_pair(playPause, playPauseBtn->getAddress()));
|
||||
views.insert(std::make_pair(queue, _queueView->getAddress()));
|
||||
}
|
||||
|
||||
M::Player::~Player()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void M::Player::set(const W::Object& value)
|
||||
{
|
||||
throw 14; //what do you expect here? not implemented, and not sure it ever would be
|
||||
}
|
||||
|
||||
void M::Player::set(W::Object* value)
|
||||
{
|
||||
set(*value);
|
||||
}
|
||||
|
||||
M::Model::ModelType M::Player::getType() const
|
||||
{
|
||||
return M::Model::player;
|
||||
}
|
||||
|
||||
void M::Player::h_subscribe(const W::Event& ev)
|
||||
{
|
||||
M::Model::h_subscribe(ev);
|
||||
|
||||
h_get(ev);
|
||||
}
|
||||
|
||||
|
||||
void M::Player::h_get(const W::Event& ev)
|
||||
{
|
||||
W::Vector* ctrls = new W::Vector();
|
||||
ItemMap::const_iterator citr = controls.begin();
|
||||
ItemMap::const_iterator cend = controls.end();
|
||||
|
||||
for (; citr != cend; ++citr) {
|
||||
W::Vocabulary* cvc = new W::Vocabulary();
|
||||
cvc->insert(u"type", new W::Uint64(cend->first));
|
||||
cvc->insert(u"address", cend->second);
|
||||
|
||||
ctrls->push(cvc);
|
||||
}
|
||||
|
||||
W::Vector* vws = new W::Vector();
|
||||
ItemMap::const_iterator vitr = views.begin();
|
||||
ItemMap::const_iterator vend = views.end();
|
||||
|
||||
for (; vitr != vend; ++vitr) {
|
||||
W::Vocabulary* vvc = new W::Vocabulary();
|
||||
vvc->insert(u"type", new W::Uint64(vend->first));
|
||||
vvc->insert(u"address", vend->second);
|
||||
|
||||
vws->push(vvc);
|
||||
}
|
||||
|
||||
W::Vocabulary* res = new W::Vocabulary();
|
||||
|
||||
res->insert(u"controls", ctrls);
|
||||
res->insert(u"views", vws);
|
||||
|
||||
response(res, W::Address({u"get"}), ev);
|
||||
}
|
||||
|
||||
void M::Player::onPlayPauseBtn()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void M::Player::h_queue(const W::Event& ev)
|
||||
{
|
||||
const W::Vocabulary& data = static_cast<const W::Vocabulary&>(ev.getData());
|
||||
|
||||
const W::Uint64& id = static_cast<const W::Uint64&>(data.at(u"id"));
|
||||
ProxySong* song = new ProxySong(id, address + W::Address{u"currentPlayback"});
|
||||
addModel(song);
|
||||
if (current == 0) {
|
||||
current = song;
|
||||
views.insert(std::make_pair(currentPlayback, song->getAddress()));
|
||||
W::Vocabulary* avc = new W::Vocabulary();
|
||||
avc->insert(u"type", new W::Uint64(currentPlayback));
|
||||
avc->insert(u"address", song->getAddress());
|
||||
|
||||
W::Vector* add = new W::Vector();
|
||||
add->push(avc);
|
||||
|
||||
W::Vocabulary* res = new W::Vocabulary();
|
||||
res->insert(u"add", add);
|
||||
res->insert(u"remove", new W::Vector());
|
||||
|
||||
broadcast(res, W::Address{u"viewsChange"});
|
||||
} else {
|
||||
_queue.push_back(song);
|
||||
_queueView->push(song->getAddress());
|
||||
}
|
||||
}
|
60
corax/models/player.h
Normal file
60
corax/models/player.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
#include <wModel/model.h>
|
||||
#include <wModel/button.h>
|
||||
#include <wModel/modelstring.h>
|
||||
#include <wModel/list.h>
|
||||
|
||||
#include <wType/vocabulary.h>
|
||||
#include <wType/vector.h>
|
||||
#include <wType/address.h>
|
||||
|
||||
#include "proxysong.h"
|
||||
/**
|
||||
* @todo write docs
|
||||
*/
|
||||
namespace M {
|
||||
class Player : public M::Model {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Player(const W::Address& address, QObject* parent = 0);
|
||||
~Player();
|
||||
|
||||
void set(const W::Object & value) override;
|
||||
void set(W::Object * value) override;
|
||||
M::Model::ModelType getType() const override;
|
||||
|
||||
enum ItemType {
|
||||
playPause,
|
||||
currentPlayback,
|
||||
queue
|
||||
};
|
||||
|
||||
protected:
|
||||
void h_subscribe(const W::Event & ev) override;
|
||||
|
||||
handler(get);
|
||||
handler(queue);
|
||||
|
||||
private:
|
||||
typedef std::map<ItemType, const W::Address&> ItemMap;
|
||||
typedef std::deque<ProxySong*> Queue;
|
||||
|
||||
ItemMap controls;
|
||||
ItemMap views;
|
||||
M::Button* playPauseBtn;
|
||||
M::List* _queueView;
|
||||
Queue _queue;
|
||||
ProxySong* current;
|
||||
|
||||
private slots:
|
||||
void onPlayPauseBtn();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PLAYER_H
|
135
corax/models/proxysong.cpp
Normal file
135
corax/models/proxysong.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
#include "proxysong.h"
|
||||
|
||||
ProxySong::ProxySong(const W::Uint64& p_id, const W::Address& p_address, QObject* parent):
|
||||
M::Vocabulary(p_address, parent),
|
||||
songCtrl(new C::Vocabulary(W::Address{u"songs", W::String(p_id.toString())})),
|
||||
albumCtrl(0),
|
||||
artistCtrl(0),
|
||||
fileId(0),
|
||||
_ready(false)
|
||||
{
|
||||
addController(songCtrl, W::String(u"Perturabo"));
|
||||
connect(songCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), SLOT(onSongNewElement(const W::String&, const W::Object&)));
|
||||
connect(songCtrl, SIGNAL(removeElement(const W::String&)), SLOT(onSongRemoveElement(const W::String&)));
|
||||
|
||||
insert(W::String(u"id"), p_id);
|
||||
insert(W::String(u"artist"), new W::String(u"undefined"));
|
||||
insert(W::String(u"album"), new W::String(u"undefined"));
|
||||
insert(W::String(u"name"), new W::String(u"undefined"));
|
||||
insert(W::String(u"image"), new W::Uint64(0));
|
||||
}
|
||||
|
||||
bool ProxySong::isReady() const
|
||||
{
|
||||
return _ready;
|
||||
}
|
||||
|
||||
ProxySong::~ProxySong()
|
||||
{
|
||||
}
|
||||
|
||||
void ProxySong::onSongNewElement(const W::String& key, const W::Object& element)
|
||||
{
|
||||
if (key == u"name") {
|
||||
insert(key, element);
|
||||
} else if (key == u"audio") {
|
||||
if (_ready) {
|
||||
_ready = false;
|
||||
emit notReady();
|
||||
}
|
||||
|
||||
fileId = static_cast<const W::Uint64&>(element);
|
||||
_ready = true;
|
||||
emit ready();
|
||||
} else if (key == u"artist") {
|
||||
if (artistCtrl != 0) {
|
||||
removeController(artistCtrl);
|
||||
disconnect(artistCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), this, SLOT(onArtistNewElement(const W::String&, const W::Object&)));
|
||||
disconnect(artistCtrl, SIGNAL(removeElement(const W::String&)), this, SLOT(onAtristRemoveElement(const W::String&)));
|
||||
artistCtrl->deleteLater();
|
||||
}
|
||||
const W::Uint64& aid = static_cast<const W::Uint64&>(element);
|
||||
artistCtrl = new C::Vocabulary(W::Address{u"artists", W::String(aid.toString())});
|
||||
addController(artistCtrl, W::String(u"Perturabo"));
|
||||
connect(artistCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), SLOT(onArtistNewElement(const W::String&, const W::Object&)));
|
||||
connect(artistCtrl, SIGNAL(removeElement(const W::String&)), SLOT(onAtristRemoveElement(const W::String&)));
|
||||
} else if (key == u"album") {
|
||||
if (albumCtrl != 0) {
|
||||
removeController(albumCtrl);
|
||||
disconnect(albumCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), this, SLOT(onAlbumNewElement(const W::String&, const W::Object&)));
|
||||
disconnect(albumCtrl, SIGNAL(removeElement(const W::String&)), this, SLOT(onAlbumRemoveElement(const W::String&)));
|
||||
albumCtrl->deleteLater();
|
||||
}
|
||||
const W::Uint64& aid = static_cast<const W::Uint64&>(element);
|
||||
albumCtrl = new C::Vocabulary(W::Address{u"albums", W::String(aid.toString())});
|
||||
addController(albumCtrl, W::String(u"Perturabo"));
|
||||
connect(albumCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), SLOT(onAlbumNewElement(const W::String&, const W::Object&)));
|
||||
connect(albumCtrl, SIGNAL(removeElement(const W::String&)), SLOT(onAlbumRemoveElement(const W::String&)));
|
||||
}
|
||||
}
|
||||
|
||||
void ProxySong::onSongRemoveElement(const W::String& key)
|
||||
{
|
||||
if (key == u"name") {
|
||||
insert(key, new W::String(u"undefined"));
|
||||
} else if (key == u"audio") {
|
||||
if (_ready) {
|
||||
_ready = false;
|
||||
fileId = W::Uint64(0);
|
||||
emit notReady();
|
||||
}
|
||||
} else if (key == u"artist") {
|
||||
if (artistCtrl != 0) {
|
||||
removeController(artistCtrl);
|
||||
disconnect(artistCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), this, SLOT(onArtistNewElement(const W::String&, const W::Object&)));
|
||||
disconnect(artistCtrl, SIGNAL(removeElement(const W::String&)), this, SLOT(onAtristRemoveElement(const W::String&)));
|
||||
artistCtrl->deleteLater();
|
||||
artistCtrl = 0;
|
||||
}
|
||||
} else if (key == u"album") {
|
||||
if (albumCtrl != 0) {
|
||||
removeController(albumCtrl);
|
||||
disconnect(albumCtrl, SIGNAL(newElement(const W::String&, const W::Object&)), this, SLOT(onAlbumNewElement(const W::String&, const W::Object&)));
|
||||
disconnect(albumCtrl, SIGNAL(removeElement(const W::String&)), this, SLOT(onAlbumRemoveElement(const W::String&)));
|
||||
albumCtrl->deleteLater();
|
||||
albumCtrl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProxySong::onAlbumNewElement(const W::String& key, const W::Object& element)
|
||||
{
|
||||
if (key == u"name") {
|
||||
insert(W::String(u"album"), element);
|
||||
} else if (key == u"image") {
|
||||
insert(key, element);
|
||||
}
|
||||
}
|
||||
|
||||
void ProxySong::onAlbumRemoveElement(const W::String& key)
|
||||
{
|
||||
if (key == u"name") {
|
||||
insert(W::String(u"album"), new W::String(u"undefined"));
|
||||
} else if (key == u"image") {
|
||||
insert(key, new W::Uint64(0));
|
||||
}
|
||||
}
|
||||
|
||||
void ProxySong::onArtistNewElement(const W::String& key, const W::Object& element)
|
||||
{
|
||||
if (key == u"name") {
|
||||
insert(W::String(u"artist"), element);
|
||||
}
|
||||
}
|
||||
|
||||
void ProxySong::onArtistRemoveElement(const W::String& key)
|
||||
{
|
||||
if (key == u"name") {
|
||||
insert(W::String(u"artist"), new W::String(u"undefined"));
|
||||
}
|
||||
}
|
||||
|
||||
const W::Uint64 & ProxySong::getFileId() const
|
||||
{
|
||||
return fileId;
|
||||
}
|
47
corax/models/proxysong.h
Normal file
47
corax/models/proxysong.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef PROXYSONG_H
|
||||
#define PROXYSONG_H
|
||||
|
||||
/**
|
||||
* @todo write docs
|
||||
*/
|
||||
#include <wType/uint64.h>
|
||||
#include <wType/address.h>
|
||||
|
||||
#include <wModel/vocabulary.h>
|
||||
|
||||
#include <wController/vocabulary.h>
|
||||
|
||||
class ProxySong : public M::Vocabulary {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProxySong(const W::Uint64& p_id, const W::Address& p_address, QObject* parent = 0);
|
||||
~ProxySong();
|
||||
|
||||
const W::Uint64& getFileId() const;
|
||||
bool isReady() const;
|
||||
|
||||
signals:
|
||||
void ready();
|
||||
void notReady();
|
||||
|
||||
private:
|
||||
C::Vocabulary* songCtrl;
|
||||
C::Vocabulary* albumCtrl;
|
||||
C::Vocabulary* artistCtrl;
|
||||
|
||||
W::Uint64 fileId;
|
||||
bool _ready;
|
||||
|
||||
private slots:
|
||||
void onSongNewElement(const W::String& key, const W::Object& element);
|
||||
void onSongRemoveElement(const W::String& key);
|
||||
|
||||
void onAlbumNewElement(const W::String& key, const W::Object& element);
|
||||
void onAlbumRemoveElement(const W::String& key);
|
||||
|
||||
void onArtistNewElement(const W::String& key, const W::Object& element);
|
||||
void onArtistRemoveElement(const W::String& key);
|
||||
|
||||
};
|
||||
|
||||
#endif // PROXYSONG_H
|
@ -276,3 +276,8 @@ bool C::Controller::isSubscribed()
|
||||
{
|
||||
return subscribed;
|
||||
}
|
||||
|
||||
const W::Address & C::Controller::getAddress() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ namespace C {
|
||||
void subscribe();
|
||||
void unsubscribe();
|
||||
bool isSubscribed();
|
||||
const W::Address& getAddress() const;
|
||||
|
||||
void removeHandler(W::Handler* handler);
|
||||
void removeController(C::Controller* ctrl);
|
||||
|
@ -215,7 +215,7 @@ void ResourceCache::h_subscribeMember(const W::Event& ev)
|
||||
M::File* modelRecord = M::File::create(readFile(*record), address + lastHops >> 1);
|
||||
delete record;
|
||||
addModel(modelRecord);
|
||||
passToHandler(ev);
|
||||
passToLocalHandler(ev);
|
||||
} catch (int err) {
|
||||
if (err == 3) {
|
||||
emit serviceMessage(QString("An attempt to create and subscribe record model in resourcecache, but it is not found. Event: ") + ev.toString().c_str());
|
||||
|
@ -14,6 +14,7 @@ set(HEADERS
|
||||
attributes.h
|
||||
icatalogue.h
|
||||
catalogue.h
|
||||
button.h
|
||||
file/file.h
|
||||
)
|
||||
|
||||
@ -25,12 +26,13 @@ set(SOURCES
|
||||
attributes.cpp
|
||||
icatalogue.cpp
|
||||
catalogue.cpp
|
||||
button.cpp
|
||||
file/file.cpp
|
||||
)
|
||||
|
||||
add_library(wModel STATIC ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(wModel Qt5::Core)
|
||||
target_link_libraries(wModel wSocket)
|
||||
target_link_libraries(wModel wDispatcher)
|
||||
target_link_libraries(wModel wServerUtils)
|
||||
target_link_libraries(wModel wType)
|
||||
target_link_libraries(wModel wController)
|
||||
|
113
lib/wModel/button.cpp
Normal file
113
lib/wModel/button.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include "button.h"
|
||||
|
||||
M::Button::Button(const W::Address& address, QObject* parent):
|
||||
M::Model(address, parent),
|
||||
enabled(true),
|
||||
hasImage(false),
|
||||
hasLabel(false),
|
||||
imageName(0),
|
||||
label(0)
|
||||
{
|
||||
W::Handler* get = W::Handler::create(address + W::Address({u"get"}), this, &M::Button::_h_get);
|
||||
W::Handler* activate = W::Handler::create(address + W::Address({u"activate"}), this, &M::Button::_h_activate);
|
||||
|
||||
addHandler(get);
|
||||
addHandler(activate);
|
||||
}
|
||||
|
||||
M::Button::~Button()
|
||||
{
|
||||
if (hasImage) {
|
||||
delete imageName;
|
||||
}
|
||||
}
|
||||
|
||||
void M::Button::setImage(const W::String& p_image)
|
||||
{
|
||||
|
||||
if (hasImage) {
|
||||
if (*imageName != p_image) {
|
||||
imageName = static_cast<W::String*>(p_image.copy());
|
||||
W::Vocabulary* vc = new W::Vocabulary();
|
||||
vc->insert(u"image", p_image);
|
||||
broadcast(vc, W::Address{u"changeImage"});
|
||||
}
|
||||
} else {
|
||||
imageName = static_cast<W::String*>(p_image.copy());
|
||||
hasImage = true;
|
||||
W::Vocabulary* vc = new W::Vocabulary();
|
||||
vc->insert(u"image", p_image);
|
||||
broadcast(vc, W::Address{u"setImage"});
|
||||
}
|
||||
hasImage = true;
|
||||
}
|
||||
|
||||
void M::Button::setEnabled(bool p_enabled)
|
||||
{
|
||||
if (enabled != p_enabled) {
|
||||
enabled = p_enabled;
|
||||
W::Vocabulary* vc = new W::Vocabulary();
|
||||
vc->insert(u"enable", new W::Boolean(enabled));
|
||||
broadcast(vc, W::Address{u"setEnabled"});
|
||||
}
|
||||
}
|
||||
|
||||
void M::Button::setLabel(const W::String& p_label)
|
||||
{
|
||||
if (hasLabel) {
|
||||
label->set(p_label);
|
||||
} else {
|
||||
label = new M::String(p_label, address + W::Address{u"label"});
|
||||
addModel(label);
|
||||
W::Vocabulary* vc = new W::Vocabulary();
|
||||
vc->insert(u"hasLabel", new W::Boolean(true));
|
||||
vc->insert(u"label", label->getAddress());
|
||||
broadcast(vc, W::Address{u"setLabel"});
|
||||
hasLabel = true;
|
||||
}
|
||||
}
|
||||
|
||||
void M::Button::h_subscribe(const W::Event& ev)
|
||||
{
|
||||
M::Model::h_subscribe(ev);
|
||||
|
||||
h_get(ev);
|
||||
}
|
||||
|
||||
void M::Button::h_get(const W::Event& ev)
|
||||
{
|
||||
W::Vocabulary* vc = new W::Vocabulary();
|
||||
vc->insert(u"hasImage", new W::Boolean(hasImage));
|
||||
if (hasImage) {
|
||||
vc->insert(u"image", imageName->copy());
|
||||
}
|
||||
vc->insert(u"hasLabel", new W::Boolean(hasLabel));
|
||||
if (hasLabel) {
|
||||
vc->insert(u"label", label->getAddress());
|
||||
}
|
||||
vc->insert(u"enabled", new W::Boolean(enabled));
|
||||
|
||||
response(vc, W::Address({u"get"}), ev);
|
||||
}
|
||||
|
||||
void M::Button::h_activate(const W::Event& ev)
|
||||
{
|
||||
if (enabled) {
|
||||
emit activated();
|
||||
}
|
||||
}
|
||||
|
||||
M::Model::ModelType M::Button::getType() const
|
||||
{
|
||||
return M::Model::button;
|
||||
}
|
||||
|
||||
void M::Button::set(const W::Object& value)
|
||||
{
|
||||
throw 14; //what do you expect here? not implemented, and not sure it ever would be
|
||||
}
|
||||
|
||||
void M::Button::set(W::Object* value)
|
||||
{
|
||||
set(*value);
|
||||
}
|
52
lib/wModel/button.h
Normal file
52
lib/wModel/button.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
|
||||
#include <wModel/model.h>
|
||||
#include <wModel/modelstring.h>
|
||||
|
||||
#include <wDispatcher/handler.h>
|
||||
|
||||
#include <wType/address.h>
|
||||
#include <wType/event.h>
|
||||
#include <wType/vocabulary.h>
|
||||
#include <wType/boolean.h>
|
||||
|
||||
/**
|
||||
* @todo write docs
|
||||
*/
|
||||
namespace M {
|
||||
class Button : public Model {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Button(const W::Address& address, QObject* parent = 0);
|
||||
~Button();
|
||||
|
||||
void setImage(const W::String& p_image);
|
||||
void setLabel(const W::String& p_label);
|
||||
void setEnabled(bool p_enabled);
|
||||
|
||||
M::Model::ModelType getType() const override;
|
||||
void set(const W::Object & value) override;
|
||||
void set(W::Object * value) override;
|
||||
|
||||
signals:
|
||||
void activated() const;
|
||||
|
||||
protected:
|
||||
void h_subscribe(const W::Event & ev) override;
|
||||
|
||||
handler(get);
|
||||
handler(activate);
|
||||
|
||||
protected:
|
||||
bool enabled;
|
||||
bool hasImage;
|
||||
bool hasLabel;
|
||||
|
||||
W::String* imageName;
|
||||
M::String* label;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // BUTTON_H
|
@ -5,12 +5,12 @@ M::Model::Model(const W::Address p_address, QObject* parent):
|
||||
address(p_address),
|
||||
registered(false),
|
||||
subscribers(new Map()),
|
||||
dispatcher(0),
|
||||
server(0),
|
||||
connector(0),
|
||||
subscribersCount(0),
|
||||
handlers(new HList()),
|
||||
properties(new W::Vector()),
|
||||
models(new MList())
|
||||
models(new MList()),
|
||||
controllers(new Controllers())
|
||||
{
|
||||
W::Handler* subscribe = W::Handler::create(address + W::Address({u"subscribe"}), this, &M::Model::_h_subscribe);
|
||||
W::Handler* unsubscribe = W::Handler::create(address + W::Address({u"unsubscribe"}), this, &M::Model::_h_unsubscribe);
|
||||
@ -21,7 +21,7 @@ M::Model::Model(const W::Address p_address, QObject* parent):
|
||||
M::Model::~Model()
|
||||
{
|
||||
if (registered) {
|
||||
unregisterModel();
|
||||
getUnregistered();
|
||||
}
|
||||
|
||||
MList::iterator itr = models->begin();
|
||||
@ -37,11 +37,19 @@ M::Model::~Model()
|
||||
for (; hItr != hEnd; ++hItr) {
|
||||
delete *hItr;
|
||||
}
|
||||
|
||||
Controllers::iterator cItr = controllers->begin();
|
||||
Controllers::iterator cEnd = controllers->end();
|
||||
|
||||
for (; cItr != cEnd; ++cItr) {
|
||||
delete cItr->first;
|
||||
}
|
||||
|
||||
delete subscribers;
|
||||
delete properties;
|
||||
delete handlers;
|
||||
delete models;
|
||||
delete controllers;
|
||||
}
|
||||
|
||||
void M::Model::addModel(M::Model* model)
|
||||
@ -49,7 +57,7 @@ void M::Model::addModel(M::Model* model)
|
||||
models->push_back(model);
|
||||
connect(model, SIGNAL(serviceMessage(const QString&)), SIGNAL(serviceMessage(const QString&)));
|
||||
if (registered) {
|
||||
model->registerModel(dispatcher, server);
|
||||
model->getRegistered(connector);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +65,7 @@ void M::Model::addHandler(W::Handler* handler)
|
||||
{
|
||||
handlers->push_back(handler);
|
||||
if (registered) {
|
||||
dispatcher->registerHandler(handler);
|
||||
connector->registerHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,21 +91,20 @@ W::Address M::Model::getAddress() const
|
||||
}
|
||||
|
||||
|
||||
void M::Model::registerModel(W::Dispatcher* dp, W::Server* srv)
|
||||
void M::Model::getRegistered(U::Connector* cn)
|
||||
{
|
||||
if (registered) {
|
||||
emit serviceMessage(QString("Model ") + address.toString().c_str() + " is already registered");
|
||||
throw 1;
|
||||
} else {
|
||||
dispatcher = dp;
|
||||
server = srv;
|
||||
connector = cn;
|
||||
|
||||
MList::iterator itr = models->begin();
|
||||
MList::iterator end = models->end();
|
||||
|
||||
for (; itr != end; ++itr) {
|
||||
M::Model* model = *itr;
|
||||
model->registerModel(dispatcher, server);
|
||||
model->getRegistered(connector);
|
||||
}
|
||||
|
||||
HList::iterator hItr = handlers->begin();
|
||||
@ -105,14 +112,21 @@ void M::Model::registerModel(W::Dispatcher* dp, W::Server* srv)
|
||||
|
||||
for (; hItr != hEnd; ++hItr) {
|
||||
W::Handler* handler = *hItr;
|
||||
dispatcher->registerHandler(handler);
|
||||
connector->registerHandler(handler);
|
||||
}
|
||||
|
||||
Controllers::iterator cItr = controllers->begin();
|
||||
Controllers::iterator cEnd = controllers->end();
|
||||
|
||||
for (; cItr != cEnd; ++cItr) {
|
||||
connector->registerController(cItr->first, cItr->second);
|
||||
}
|
||||
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
|
||||
void M::Model::unregisterModel()
|
||||
void M::Model::getUnregistered()
|
||||
{
|
||||
if (!registered) {
|
||||
emit serviceMessage(QString("Model ") + address.toString().c_str() + " is not registered");
|
||||
@ -123,7 +137,7 @@ void M::Model::unregisterModel()
|
||||
|
||||
for (; itr != end; ++itr) {
|
||||
Model* model = *itr;
|
||||
model->unregisterModel();
|
||||
model->getUnregistered();
|
||||
}
|
||||
|
||||
HList::iterator hItr = handlers->begin();
|
||||
@ -131,21 +145,27 @@ void M::Model::unregisterModel()
|
||||
|
||||
for (; hItr != hEnd; ++hItr) {
|
||||
W::Handler* handler = *hItr;
|
||||
dispatcher->unregisterHandler(handler);
|
||||
connector->unregisterHandler(handler);
|
||||
}
|
||||
|
||||
Map::iterator sItr = subscribers->begin();
|
||||
Map::iterator sEnd = subscribers->end();
|
||||
|
||||
for (; sItr != sEnd; ++sItr) {
|
||||
const W::Socket& socket = server->getConnection(sItr->first);
|
||||
disconnect(&socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
const W::Socket* socket = connector->getConnection(sItr->first);
|
||||
disconnect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
}
|
||||
subscribers->clear();
|
||||
subscribersCount = 0;
|
||||
|
||||
dispatcher = 0;
|
||||
server = 0;
|
||||
Controllers::iterator cItr = controllers->begin();
|
||||
Controllers::iterator cEnd = controllers->end();
|
||||
|
||||
for (; cItr != cEnd; ++cItr) {
|
||||
connector->unregisterController(cItr->first, cItr->second);
|
||||
}
|
||||
|
||||
connector = 0;
|
||||
|
||||
registered = false;
|
||||
}
|
||||
@ -162,7 +182,6 @@ void M::Model::h_subscribe(const W::Event& ev)
|
||||
params = static_cast<const W::Vocabulary&>(vc.at(u"params"));
|
||||
}
|
||||
|
||||
|
||||
Map::iterator sItr = subscribers->find(id);
|
||||
|
||||
if (sItr == subscribers->end()) {
|
||||
@ -171,8 +190,8 @@ void M::Model::h_subscribe(const W::Event& ev)
|
||||
emit serviceMessage(QString("Model ") + address.toString().c_str() + ": something completely wrong happened");
|
||||
throw 3;
|
||||
}
|
||||
const W::Socket& socket = server->getConnection(id);
|
||||
connect(&socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
const W::Socket* socket = connector->getConnection(id);
|
||||
connect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
sItr = pair.first;
|
||||
}
|
||||
SMap::const_iterator oItr = sItr->second.find(source);
|
||||
@ -238,8 +257,8 @@ void M::Model::h_unsubscribe(const W::Event& ev)
|
||||
|
||||
smap.erase(sItr);
|
||||
if (smap.size() == 0) {
|
||||
const W::Socket& socket = server->getConnection(itr->first);
|
||||
disconnect(&socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
const W::Socket* socket = connector->getConnection(itr->first);
|
||||
disconnect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
subscribers->erase(itr);
|
||||
}
|
||||
--subscribersCount;
|
||||
@ -256,7 +275,7 @@ void M::Model::send(W::Vocabulary* vc, const W::Address& destination, uint64_t c
|
||||
}
|
||||
W::Event ev(destination, vc);
|
||||
ev.setSenderId(connectionId);
|
||||
server->getConnection(connectionId).send(ev);
|
||||
connector->getConnection(connectionId)->send(ev);
|
||||
}
|
||||
|
||||
void M::Model::response(W::Vocabulary* vc, const W::Address& handlerAddress, const W::Event& src)
|
||||
@ -272,7 +291,7 @@ void M::Model::response(W::Vocabulary* vc, const W::Address& handlerAddress, con
|
||||
|
||||
W::Event ev(source + handlerAddress, vc);
|
||||
ev.setSenderId(id);
|
||||
server->getConnection(id).send(ev);
|
||||
connector->getConnection(id)->send(ev);
|
||||
}
|
||||
|
||||
void M::Model::fakeResponse(W::Vocabulary* vc, const W::Address& handlerAddress, const W::Address& sourceAddress, const W::Event& src)
|
||||
@ -288,7 +307,7 @@ void M::Model::fakeResponse(W::Vocabulary* vc, const W::Address& handlerAddress,
|
||||
|
||||
W::Event ev(source + handlerAddress, vc);
|
||||
ev.setSenderId(id);
|
||||
server->getConnection(id).send(ev);
|
||||
connector->getConnection(id)->send(ev);
|
||||
}
|
||||
|
||||
void M::Model::broadcast(W::Vocabulary* vc, const W::Address& handlerAddress)
|
||||
@ -307,7 +326,7 @@ void M::Model::broadcast(W::Vocabulary* vc, const W::Address& handlerAddress)
|
||||
for (;oItr != oEnd; ++oItr) {
|
||||
W::Event ev(oItr->first + handlerAddress, vc->copy());
|
||||
ev.setSenderId(itr->first);
|
||||
server->getConnection(itr->first).send(ev);
|
||||
connector->getConnection(itr->first)->send(ev);
|
||||
}
|
||||
}
|
||||
delete vc;
|
||||
@ -317,23 +336,54 @@ void M::Model::removeHandler(W::Handler* handler)
|
||||
{
|
||||
handlers->erase(handler);
|
||||
if (registered) {
|
||||
dispatcher->unregisterHandler(handler);
|
||||
connector->unregisterHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
void M::Model::removeModel(M::Model* model)
|
||||
{
|
||||
models->erase(model);
|
||||
disconnect(model, SIGNAL(serviceMessage(const QString&)), this, SIGNAL(serviceMessage(const QString&)));
|
||||
if (registered) {
|
||||
model->unregisterModel();
|
||||
model->getUnregistered();
|
||||
}
|
||||
}
|
||||
|
||||
void M::Model::passToHandler(const W::Event& event) const
|
||||
void M::Model::passToLocalHandler(const W::Event& event) const
|
||||
{
|
||||
if (registered) {
|
||||
dispatcher->pass(event);
|
||||
connector->passThroughDispatcher(event);
|
||||
} else {
|
||||
emit serviceMessage(QString("An attempt to pass event to dispatcher from unregistered model\nModel address ") + address.toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void M::Model::addController(C::Controller* ctrl, const W::String& nodeName)
|
||||
{
|
||||
Controllers::const_iterator itr = controllers->find(ctrl);
|
||||
if (itr != controllers->end()) {
|
||||
emit serviceMessage(QString("An attempt to add controller ") + ctrl->getAddress().toString().c_str() + QString(" for the second time in model ") + address.toString().c_str());
|
||||
throw 9;
|
||||
}
|
||||
controllers->insert(std::make_pair(ctrl, nodeName));
|
||||
connect(ctrl, SIGNAL(serviceMessage(const QString&)), SIGNAL(serviceMessage(const QString&)));
|
||||
if (registered) {
|
||||
connector->registerController(ctrl, nodeName);;
|
||||
}
|
||||
}
|
||||
|
||||
void M::Model::removeController(C::Controller* ctrl)
|
||||
{
|
||||
Controllers::const_iterator itr = controllers->find(ctrl);
|
||||
if (itr == controllers->end()) {
|
||||
emit serviceMessage(QString("An attempt to remove absent controller ") + ctrl->getAddress().toString().c_str() + QString(" from the model ") + address.toString().c_str());
|
||||
throw 10;
|
||||
}
|
||||
|
||||
disconnect(ctrl, SIGNAL(serviceMessage(const QString&)), this, SIGNAL(serviceMessage(const QString&)));
|
||||
if (registered) {
|
||||
connector->unregisterController(itr->first, itr->second);
|
||||
}
|
||||
controllers->erase(itr);
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,10 @@
|
||||
#include <wType/event.h>
|
||||
#include <wType/string.h>
|
||||
#include <wSocket/socket.h>
|
||||
#include <wSocket/server.h>
|
||||
#include <wDispatcher/dispatcher.h>
|
||||
#include <wDispatcher/handler.h>
|
||||
#include <wContainer/order.h>
|
||||
#include <wServerUtils/connector.h>
|
||||
#include <wController/controller.h>
|
||||
|
||||
namespace M {
|
||||
|
||||
@ -29,10 +29,15 @@ namespace M {
|
||||
list,
|
||||
vocabulary,
|
||||
catalogue,
|
||||
image,
|
||||
button,
|
||||
model,
|
||||
|
||||
attributes = 50,
|
||||
file,
|
||||
resourceCache
|
||||
resourceCache,
|
||||
|
||||
player = 107
|
||||
};
|
||||
|
||||
Model(const W::Address p_address, QObject* parent = 0);
|
||||
@ -46,13 +51,15 @@ namespace M {
|
||||
void addModel(M::Model* model);
|
||||
void addHandler(W::Handler* handler);
|
||||
void addProperty(const W::String& value, const W::String& name);
|
||||
void addController(C::Controller* ctrl, const W::String& nodeName);
|
||||
W::Address getAddress() const;
|
||||
void registerModel(W::Dispatcher* dp, W::Server* srv);
|
||||
void unregisterModel();
|
||||
void getRegistered(U::Connector* connector);
|
||||
void getUnregistered();
|
||||
|
||||
void removeHandler(W::Handler* handler);
|
||||
void removeModel(M::Model* model);
|
||||
void passToHandler(const W::Event& event) const;
|
||||
void removeController(C::Controller* ctrl);
|
||||
void passToLocalHandler(const W::Event& event) const;
|
||||
|
||||
signals:
|
||||
void serviceMessage(const QString& msg) const;
|
||||
@ -76,13 +83,14 @@ namespace M {
|
||||
private:
|
||||
typedef W::Order<W::Handler*> HList;
|
||||
typedef W::Order<M::Model*> MList;
|
||||
typedef std::map<C::Controller*, W::String> Controllers;
|
||||
|
||||
W::Dispatcher* dispatcher;
|
||||
W::Server* server;
|
||||
U::Connector* connector;
|
||||
uint64_t subscribersCount;
|
||||
HList* handlers;
|
||||
W::Vector* properties;
|
||||
MList* models;
|
||||
Controllers* controllers;
|
||||
|
||||
private slots:
|
||||
void onSocketDisconnected();
|
||||
|
@ -12,8 +12,7 @@
|
||||
namespace M {
|
||||
class ICatalogue;
|
||||
|
||||
class Vocabulary : public M::Model
|
||||
{
|
||||
class Vocabulary : public M::Model {
|
||||
friend class ICatalogue;
|
||||
public:
|
||||
Vocabulary(const W::Address p_address, QObject* parent = 0);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "connector.h"
|
||||
#include "commands.h"
|
||||
|
||||
U::Connector::Connector(W::Dispatcher* dp, W::Server* srv, U::Commands* cmds, QObject* parent):
|
||||
QObject(parent),
|
||||
@ -6,7 +7,8 @@ U::Connector::Connector(W::Dispatcher* dp, W::Server* srv, U::Commands* cmds, QO
|
||||
server(srv),
|
||||
commands(cmds),
|
||||
nodes(),
|
||||
ignoredNodes()
|
||||
ignoredNodes(),
|
||||
controllers()
|
||||
{
|
||||
connect(server, SIGNAL(newConnection(const W::Socket&)), SLOT(onNewConnection(const W::Socket&)));
|
||||
connect(server, SIGNAL(closedConnection(const W::Socket&)), SLOT(onClosedConnection(const W::Socket&)));
|
||||
@ -30,6 +32,17 @@ U::Connector::~Connector()
|
||||
for (; itr != end; ++itr) {
|
||||
commands->removeCommand(dc + itr->first);
|
||||
}
|
||||
|
||||
std::multimap<W::String, C::Controller*>::const_iterator cbeg = controllers.begin();
|
||||
std::multimap<W::String, C::Controller*>::const_iterator cend = controllers.end();
|
||||
|
||||
for (; cbeg != cend; ++cbeg) {
|
||||
C::Controller* ctrl = cbeg->second;
|
||||
if (ctrl->isSubscribed()) {
|
||||
ctrl->unsubscribe();
|
||||
ctrl->unregisterController();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void U::Connector::addIgnoredNode(const W::String& name)
|
||||
@ -43,7 +56,7 @@ void U::Connector::sendTo(const W::String& name, const W::Event& event)
|
||||
if (itr != nodes.end()) {
|
||||
throw new NodeAccessError(name);
|
||||
} else {
|
||||
server->getConnection(itr->second).send(event);
|
||||
server->getConnection(itr->second)->send(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +82,14 @@ void U::Connector::onNewConnection(const W::Socket& socket)
|
||||
emit serviceMessage(QString("New connection, id: ") + socket.getId().toString().c_str());
|
||||
connect(&socket, SIGNAL(message(const W::Event&)), dispatcher, SLOT(pass(const W::Event&)));
|
||||
|
||||
std::multimap<W::String, C::Controller*>::const_iterator beg = controllers.lower_bound(name);
|
||||
std::multimap<W::String, C::Controller*>::const_iterator end = controllers.upper_bound(name);
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
beg->second->registerController(dispatcher, &socket);
|
||||
beg->second->subscribe();
|
||||
}
|
||||
|
||||
emit nodeConnected(name);
|
||||
}
|
||||
} else {
|
||||
@ -90,6 +111,14 @@ void U::Connector::onClosedConnection(const W::Socket& socket)
|
||||
if (ign == ignoredNodes.end()) {
|
||||
Map::const_iterator itr = nodes.find(name);
|
||||
if (itr != nodes.end()) {
|
||||
std::multimap<W::String, C::Controller*>::const_iterator beg = controllers.lower_bound(name);
|
||||
std::multimap<W::String, C::Controller*>::const_iterator end = controllers.upper_bound(name);
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
beg->second->unsubscribe();
|
||||
beg->second->unregisterController();
|
||||
}
|
||||
|
||||
emit nodeDisconnected(name);
|
||||
commands->removeCommand(W::String(u"disconnect") + name);
|
||||
nodes.erase(itr);
|
||||
@ -114,7 +143,7 @@ void U::Connector::h_disconnect(const W::Event& ev)
|
||||
server->closeConnection(itr->second);
|
||||
}
|
||||
|
||||
const W::Socket& U::Connector::getNodeSocket(const W::String& name)
|
||||
const W::Socket* U::Connector::getNodeSocket(const W::String& name)
|
||||
{
|
||||
Map::const_iterator itr = nodes.find(name);
|
||||
if (itr == nodes.end()) {
|
||||
@ -122,3 +151,62 @@ const W::Socket& U::Connector::getNodeSocket(const W::String& name)
|
||||
}
|
||||
return server->getConnection(itr->second);
|
||||
}
|
||||
|
||||
void U::Connector::registerHandler(W::Handler* handler)
|
||||
{
|
||||
dispatcher->registerHandler(handler);
|
||||
}
|
||||
|
||||
void U::Connector::unregisterHandler(W::Handler* handler)
|
||||
{
|
||||
dispatcher->unregisterHandler(handler);
|
||||
}
|
||||
|
||||
const W::Socket * U::Connector::getConnection(uint64_t p_id) const
|
||||
{
|
||||
return server->getConnection(p_id);
|
||||
}
|
||||
|
||||
void U::Connector::passThroughDispatcher(const W::Event& ev) const
|
||||
{
|
||||
dispatcher->pass(ev);
|
||||
}
|
||||
|
||||
void U::Connector::registerController(C::Controller* ctrl, const W::String& node)
|
||||
{
|
||||
std::set<W::String>::const_iterator iitr = ignoredNodes.find(node);
|
||||
if (iitr != ignoredNodes.end()) {
|
||||
throw 3; //this means you're trying to receive something from one of ignored nodes, which never going to be handled in connector, most probably it's a mistake
|
||||
}
|
||||
controllers.insert(std::make_pair(node, ctrl));
|
||||
Map::const_iterator itr = nodes.find(node);
|
||||
if (itr != nodes.end()) {
|
||||
ctrl->registerController(dispatcher, server->getConnection(itr->second));
|
||||
ctrl->subscribe(); //let's say I always need them subscribed, for now at least
|
||||
}
|
||||
}
|
||||
|
||||
void U::Connector::unregisterController(C::Controller* ctrl, const W::String& node)
|
||||
{
|
||||
bool found = false;
|
||||
std::multimap<W::String, C::Controller*>::const_iterator beg = controllers.lower_bound(node);
|
||||
std::multimap<W::String, C::Controller*>::const_iterator end = controllers.upper_bound(node);
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
if (beg->second == ctrl) {
|
||||
found = true; //TODO make a proper way to store 'em
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
throw 4;
|
||||
}
|
||||
|
||||
if (ctrl->isSubscribed()) {
|
||||
ctrl->unsubscribe();
|
||||
ctrl->unregisterController();
|
||||
}
|
||||
controllers.erase(beg);
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
#ifndef CONNECTOR_H
|
||||
#define CONNECTOR_H
|
||||
|
||||
#include <utils/defines.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <wDispatcher/dispatcher.h>
|
||||
#include <wDispatcher/handler.h>
|
||||
|
||||
#include <wSocket/socket.h>
|
||||
#include <wSocket/server.h>
|
||||
@ -16,9 +19,11 @@
|
||||
|
||||
#include <utils/exception.h>
|
||||
|
||||
#include "commands.h"
|
||||
#include <wController/controller.h>
|
||||
|
||||
namespace U {
|
||||
class Commands;
|
||||
|
||||
class Connector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -29,7 +34,13 @@ namespace U {
|
||||
|
||||
void addIgnoredNode(const W::String& name);
|
||||
void sendTo(const W::String& name, const W::Event& event);
|
||||
const W::Socket& getNodeSocket(const W::String& name);
|
||||
const W::Socket* getNodeSocket(const W::String& name);
|
||||
void registerHandler(W::Handler* handler);
|
||||
void unregisterHandler(W::Handler* handler);
|
||||
const W::Socket* getConnection(uint64_t p_id) const;
|
||||
void passThroughDispatcher(const W::Event& ev) const;
|
||||
void registerController(C::Controller* ctrl, const W::String& node);
|
||||
void unregisterController(C::Controller* ctrl, const W::String& node);
|
||||
|
||||
signals:
|
||||
void serviceMessage(const QString& msg);
|
||||
@ -42,6 +53,7 @@ namespace U {
|
||||
U::Commands* commands;
|
||||
Map nodes;
|
||||
std::set<W::String> ignoredNodes;
|
||||
std::multimap<W::String, C::Controller*> controllers;
|
||||
|
||||
protected:
|
||||
handler(connect);
|
||||
|
@ -44,14 +44,14 @@ void W::Server::stop()
|
||||
}
|
||||
}
|
||||
|
||||
const W::Socket& W::Server::getConnection(uint64_t p_id) const
|
||||
const W::Socket* W::Server::getConnection(uint64_t p_id) const
|
||||
{
|
||||
std::map<uint64_t, Socket*>::const_iterator itr = connections.find(p_id);
|
||||
if (itr == connections.end()) {
|
||||
throw new SocketAccessError();
|
||||
}
|
||||
|
||||
return *(itr->second);
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
uint64_t W::Server::getConnectionsCount() const
|
||||
|
@ -27,7 +27,7 @@ namespace W
|
||||
void listen(uint16_t port);
|
||||
void stop();
|
||||
|
||||
const Socket& getConnection(uint64_t p_id) const;
|
||||
const Socket* getConnection(uint64_t p_id) const;
|
||||
uint64_t getConnectionsCount() const;
|
||||
void closeConnection(uint64_t p_id);
|
||||
void openConnection(const String& addr, const Uint64& port);
|
||||
|
@ -102,5 +102,7 @@ W::Object::StdStr W::Object::getTypeName(W::Object::objectType type)
|
||||
case blob:
|
||||
return "Blob";
|
||||
}
|
||||
|
||||
throw 5;
|
||||
}
|
||||
|
||||
|
69
libjs/wController/button.js
Normal file
69
libjs/wController/button.js
Normal file
@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
|
||||
var Controller = require("./controller");
|
||||
var String = require("./string");
|
||||
var Vocabulary = require("../wType/vocabulary");
|
||||
|
||||
var Button = Controller.inherit({
|
||||
"className": "Button",
|
||||
"constructor": function(addr) {
|
||||
Controller.fn.constructor.call(this, addr);
|
||||
|
||||
this.enabled = false;
|
||||
this.hasLabel = false;
|
||||
|
||||
this.addHandler("get");
|
||||
this.addHandler("setLabel");
|
||||
this.addHandler("setImage");
|
||||
this.addHandler("setEnabled");
|
||||
this.addHandler("changeImage");
|
||||
},
|
||||
"destructor": function() {
|
||||
|
||||
Controller.fn.destructor.call(this);
|
||||
},
|
||||
"activate": function() {
|
||||
if (this.enabled) {
|
||||
this.send(new Vocabulary, "activate");
|
||||
}
|
||||
},
|
||||
"_h_changeImage": function(ev) {
|
||||
|
||||
},
|
||||
"_h_get": function(ev) {
|
||||
this._h_setLabel(ev);
|
||||
this._h_setImage(ev);
|
||||
this._h_setEnabled(ev);
|
||||
},
|
||||
"_h_setEnabled": function(ev) {
|
||||
var data = ev.getData();
|
||||
|
||||
var enabled = data.at("enabled").valueOf();
|
||||
if (this.enabled !== enabled) {
|
||||
this.enabled = enabled;
|
||||
this.trigger("setEnabled", this.enabled);
|
||||
}
|
||||
},
|
||||
"_h_setLabel": function(ev) {
|
||||
var data = ev.getData();
|
||||
var hasLabel = data.at("hasLabel").valueOf();
|
||||
|
||||
if (hasLabel !== this.hasLabel) {
|
||||
this.hasLabel = hasLabel;
|
||||
if (hasLabel) {
|
||||
this.label = new String(data.at("label").clone());
|
||||
this.addController(this.label);
|
||||
this.trigger("setLabel", true, this.label);
|
||||
} else {
|
||||
this.trigger("setLabel", false);
|
||||
this.removeController(this.label);
|
||||
this.label.destructor();
|
||||
}
|
||||
}
|
||||
},
|
||||
"_h_setImage": function(ev) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Button;
|
@ -328,8 +328,10 @@ Controller.ModelType = {
|
||||
String: 0,
|
||||
List: 1,
|
||||
Vocabulary: 2,
|
||||
Image: 3,
|
||||
Controller: 4,
|
||||
Catalogue: 3,
|
||||
Image: 4,
|
||||
Button: 5,
|
||||
Controller: 6,
|
||||
|
||||
Attributes: 50,
|
||||
|
||||
@ -339,15 +341,18 @@ Controller.ModelType = {
|
||||
PageStorage: 103,
|
||||
PanesList: 104,
|
||||
Theme: 105,
|
||||
ThemeStorage: 106
|
||||
ThemeStorage: 106,
|
||||
Player: 107
|
||||
};
|
||||
|
||||
Controller.ReversedModelType = {
|
||||
"0": "String",
|
||||
"1": "List",
|
||||
"2": "Vocabulary",
|
||||
"3": "Image",
|
||||
"4": "Controller",
|
||||
"3": "Catalogue",
|
||||
"4": "Image",
|
||||
"5": "Button",
|
||||
"6": "Controller",
|
||||
|
||||
"50": "Attributes",
|
||||
|
||||
@ -357,7 +362,8 @@ Controller.ReversedModelType = {
|
||||
"103": "PageStorage",
|
||||
"104": "PanesList",
|
||||
"105": "Theme",
|
||||
"106": "ThemeStorage"
|
||||
"106": "ThemeStorage",
|
||||
"107": "Player"
|
||||
};
|
||||
|
||||
Controller.ModelTypesPaths = {
|
||||
@ -372,7 +378,10 @@ Controller.ModelTypesPaths = {
|
||||
PanesList: "./panesList", //resolve as dependency
|
||||
Theme: "./theme", //resolve as dependency
|
||||
ThemeStorage: "./themeStorage", //resolve as dependency
|
||||
Image: "./image" //resolve as dependency
|
||||
Image: "./image", //resolve as dependency
|
||||
Button: "./button", //resolve as dependency
|
||||
Catalogue: "./catalogue", //resolve as dependency
|
||||
Player: "./player" //resolve as dependency
|
||||
};
|
||||
|
||||
Controller.constructors = {
|
||||
|
@ -10,16 +10,12 @@ var Link = Controller.inherit({
|
||||
"constructor": function(addr) {
|
||||
Controller.fn.constructor.call(this, addr);
|
||||
|
||||
var hop = new Address(["label"]);
|
||||
|
||||
this.targetAddress = new Address([]);
|
||||
this.label = new String(addr['+'](hop));
|
||||
|
||||
this.addController(this.label);
|
||||
|
||||
this.addHandler("get");
|
||||
|
||||
hop.destructor();
|
||||
},
|
||||
"destructor": function() {
|
||||
this.targetAddress.destructor();
|
||||
@ -35,4 +31,6 @@ var Link = Controller.inherit({
|
||||
}
|
||||
});
|
||||
|
||||
var hop = new Address(["label"]);
|
||||
|
||||
module.exports = Link;
|
||||
|
@ -13,5 +13,6 @@ configure_file(themeStorage.js themeStorage.js)
|
||||
configure_file(vocabulary.js vocabulary.js)
|
||||
configure_file(attributes.js attributes.js)
|
||||
configure_file(image.js image.js)
|
||||
configure_file(button.js button.js)
|
||||
|
||||
add_subdirectory(proxy)
|
||||
|
90
libjs/wModel/button.js
Normal file
90
libjs/wModel/button.js
Normal file
@ -0,0 +1,90 @@
|
||||
"use strict";
|
||||
|
||||
var Model = require("./model");
|
||||
var ModelString = require("./string");
|
||||
|
||||
var Vocabulary = require("../wType/vocabulary");
|
||||
var Boolean = require("../wType/boolean");
|
||||
var Address = require("../wType/address");
|
||||
var String = require("../wType/string");
|
||||
|
||||
var Button = Model.inherit({
|
||||
"className": "Button",
|
||||
"constructor": function(address) {
|
||||
Model.fn.constructor.call(this, address);
|
||||
|
||||
this._enabled = true;
|
||||
this._hasImage = false;
|
||||
this._hasLabel =false;
|
||||
this._imageName = undefined;
|
||||
this._label = undefined;
|
||||
|
||||
this.addHandler("get");
|
||||
this.addHandler("activate");
|
||||
},
|
||||
"setImage": function(name) {
|
||||
if (this._hasImage) {
|
||||
if (this._imageName !== name) {
|
||||
this._image = name;
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("image", new String(this._imageName));
|
||||
this.broadcast(vc, "changeImage");
|
||||
}
|
||||
} else {
|
||||
this._image = name;
|
||||
this._hasImage = true;
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("image", new String(this._imageName));
|
||||
this.broadcast(vc, "setImage");
|
||||
}
|
||||
},
|
||||
"setEnabled": function(enabled) {
|
||||
if (enabled !== this._enabled) {
|
||||
this._enabled = enabled;
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("enabled", new Boolean(this._enabled));
|
||||
this.broadcast(vc, "setEnabled");
|
||||
}
|
||||
},
|
||||
"setLabel": function(text) {
|
||||
if (this._hasLabel) {
|
||||
this._label.set(text);
|
||||
} else {
|
||||
this._label = new ModelString(this._address["+"](labelHop), text);
|
||||
this.addModel(this._label);
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("hasLabel", new Boolean(true));
|
||||
vc.insert("label", this._label.getAddress());
|
||||
this.broadcast(vc, "setLabel");
|
||||
this._hasLabel = true;
|
||||
}
|
||||
},
|
||||
"_h_subscribe": function(ev) {
|
||||
Model.fn._h_subscribe.call(this, ev);
|
||||
|
||||
this._h_get(ev);
|
||||
},
|
||||
"_h_get": function(ev) {
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("hasImage", new Boolean(this._hasImage));
|
||||
if (this._hasImage) {
|
||||
vc.insert("image", new String(this._imageName));
|
||||
}
|
||||
vc.insert("hasLabel", new Boolean(this._hasLabel));
|
||||
if (this._hasLabel) {
|
||||
vc.insert("label", this._label.getAddress());
|
||||
}
|
||||
vc.insert("enabled", new Boolean(this._enabled));
|
||||
|
||||
this.response(vc, "get", ev);
|
||||
},
|
||||
"_h_activate": function() {
|
||||
if (this._enabled) {
|
||||
this.trigger("activated");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var labelHop = new Address(["label"]);
|
||||
|
||||
module.exports = Button;
|
@ -299,8 +299,10 @@ Model.ModelType = {
|
||||
String: 0,
|
||||
List: 1,
|
||||
Vocabulary: 2,
|
||||
Image: 3,
|
||||
Model: 4,
|
||||
//Catalogue: 3,
|
||||
Image: 4,
|
||||
Button: 5,
|
||||
Model: 6,
|
||||
|
||||
Attributes: 50,
|
||||
|
||||
@ -310,7 +312,8 @@ Model.ModelType = {
|
||||
PageStorage: 103,
|
||||
PanesList: 104,
|
||||
Theme: 105,
|
||||
ThemeStorage: 106
|
||||
ThemeStorage: 106,
|
||||
Player: 107
|
||||
};
|
||||
|
||||
module.exports = Model;
|
||||
|
@ -45,3 +45,7 @@ div.dragging .draggable {
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
@ -17,3 +17,4 @@ add_jslib(wController/localModel.js lib/wController/localModel ${LORGAR_DIR} bro
|
||||
add_jslib(wController/imagePane.js lib/wController/imagePane ${LORGAR_DIR} browser)
|
||||
add_jslib(wController/file/file.js lib/wController/file/file ${LORGAR_DIR} browser)
|
||||
add_jslib(wController/image.js lib/wController/image ${LORGAR_DIR} browser)
|
||||
add_jslib(wController/button.js lib/wController/button ${LORGAR_DIR} browser)
|
||||
|
@ -36,8 +36,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
Controller.initialize(["String", "List", "Vocabulary", "Page", "PanesList", "Link", "Image"], waiter.check.bind(waiter, "controllers"));
|
||||
View.initialize(["Label", "Page", "PanesList", "Nav", "Image"], waiter.check.bind(waiter, "views"));
|
||||
Controller.initialize(["String", "List", "Vocabulary", "Page", "PanesList", "Link", "Image", "Button"], waiter.check.bind(waiter, "controllers"));
|
||||
View.initialize(["Label", "Page", "PanesList", "Nav", "Image", "Button"], waiter.check.bind(waiter, "views"));
|
||||
|
||||
var test = new Test();
|
||||
test.run();
|
||||
|
@ -11,5 +11,6 @@ configure_file(mainLayout.js mainLayout.js)
|
||||
configure_file(page.js page.js)
|
||||
configure_file(pane.js pane.js)
|
||||
configure_file(image.js image.js)
|
||||
configure_file(button.js button.js)
|
||||
|
||||
add_subdirectory(helpers)
|
||||
|
95
lorgar/views/button.js
Normal file
95
lorgar/views/button.js
Normal file
@ -0,0 +1,95 @@
|
||||
"use strict";
|
||||
(function() {
|
||||
var moduleName = "views/button";
|
||||
|
||||
var deps = [];
|
||||
deps.push("views/layout");
|
||||
deps.push("views/label");
|
||||
|
||||
define(moduleName, deps, function() {
|
||||
var Layout = require("views/layout");
|
||||
var Label = require("views/label");
|
||||
|
||||
var Button = Layout.inherit({
|
||||
"className": "Button",
|
||||
"constructor": function(controller, options) {
|
||||
var base = {
|
||||
padding: 5
|
||||
};
|
||||
W.extend(base, options)
|
||||
Layout.fn.constructor.call(this, controller, base);
|
||||
|
||||
this.addClass("hoverable");
|
||||
this._enabled = true;
|
||||
this._hasLabel = false;
|
||||
this._e.addEventListener("click", this._onClick.bind(this), false);
|
||||
|
||||
controller.on("setEnabled", this._onSetEnabled, this);
|
||||
controller.on("setLabel", this._onSetLabel, this);
|
||||
},
|
||||
"destructor": function() {
|
||||
this._f.off("setEnabled", this._onSetEnabled, this);
|
||||
this._f.off("setLabel", this._onSetLabel, this);
|
||||
|
||||
Layout.fn.destructor.call(this);
|
||||
},
|
||||
"append": function(child, aligment, index) {
|
||||
this._updateLimits();
|
||||
|
||||
Layout.fn.append.call(this, child, aligment, index);
|
||||
},
|
||||
"_onChildChangeLimits": function(child) {
|
||||
this._updateLimits();
|
||||
|
||||
Layout.fn._onChildChangeLimits.call(this, child);
|
||||
},
|
||||
"_onClick": function() {
|
||||
if (this._enabled) {
|
||||
this._f.activate();
|
||||
}
|
||||
},
|
||||
"_onSetEnabled": function(enabled) {
|
||||
if (this._enabled !== enabled) {
|
||||
this._enabled = enabled;
|
||||
if (this._enabled) {
|
||||
this.addClass("hoverable");
|
||||
this.removeClass("disabled");
|
||||
} else {
|
||||
this.removeClass("hoverable");
|
||||
this.addClass("disabled");
|
||||
}
|
||||
}
|
||||
},
|
||||
"_onSetLabel": function(hasLabel, label) {
|
||||
if (this._hasLabel !== hasLabel) {
|
||||
this._hasLabel = hasLabel;
|
||||
if (this._hasLabel) {
|
||||
this._label = new Label(label);
|
||||
this.append(this._label, Layout.Aligment.CenterCenter);
|
||||
} else {
|
||||
this._label.destructor();
|
||||
delete this._label();
|
||||
}
|
||||
}
|
||||
},
|
||||
"_updateLimits": function() {
|
||||
var minWidth = this._o.padding * 2;
|
||||
var maxWidth = this._o.padding * 2;
|
||||
var minHeight = this._o.padding * 2;
|
||||
var maxHeight = this._o.padding * 2;
|
||||
|
||||
if (this._hasLabel) {
|
||||
minWidth += this._label._o.minWidth;
|
||||
minHeight += this._label._o.minHeight;
|
||||
maxWidth += this._label._o.maxWidth;
|
||||
maxHeight += this._label._o.maxHeight;
|
||||
}
|
||||
|
||||
this._setLimits(minWidth, minHeight, maxWidth, maxHeight);
|
||||
}
|
||||
});
|
||||
|
||||
return Button;
|
||||
})
|
||||
})();
|
||||
|
@ -76,8 +76,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this._w !== undefined && this._h !== undefined) {
|
||||
child.setSize(this._w, this._h);
|
||||
index = index || this._c.length - 1;
|
||||
var c = this._c[index];
|
||||
this._positionElement(c);
|
||||
}
|
||||
},
|
||||
"clear": function() {
|
||||
|
@ -191,9 +191,12 @@
|
||||
}
|
||||
if (needToTell) {
|
||||
this.trigger("changeLimits", this);
|
||||
if (this._w !== undefined && this._h !== undefined) {
|
||||
this.setSize(this._w, this._h);
|
||||
}
|
||||
}
|
||||
|
||||
return needToTell && this._events.changeLimits && this._events.changeLimits.length; //to see if someone actually going to listen that event
|
||||
return needToTell && this._events.changeLimits && this._events.changeLimits.length; //to see if someone actually going to listen that event, if not - return result
|
||||
},
|
||||
"setMaxSize": function(w, h) {
|
||||
this._o.maxWidth = w;
|
||||
@ -284,22 +287,27 @@
|
||||
View.ViewType = {
|
||||
Label: 0,
|
||||
|
||||
Image: 3,
|
||||
View: 4,
|
||||
Image: 4,
|
||||
Button: 5,
|
||||
View: 6,
|
||||
|
||||
Page: 102,
|
||||
PanesList: 104
|
||||
PanesList: 104,
|
||||
Player: 107
|
||||
};
|
||||
|
||||
View.ReversedViewType = {
|
||||
"0": "Label",
|
||||
|
||||
"3": "Image",
|
||||
"4": "View",
|
||||
"4": "Image",
|
||||
"5": "Button",
|
||||
"6": "View",
|
||||
|
||||
"101": "Nav",
|
||||
"102": "Page",
|
||||
"104": "PanesList"
|
||||
"104": "PanesList",
|
||||
|
||||
"107": "Player"
|
||||
};
|
||||
|
||||
View.ViewTypesPaths = {
|
||||
@ -307,7 +315,9 @@
|
||||
Nav: "views/nav",
|
||||
Page: "views/page",
|
||||
PanesList: "views/panesList",
|
||||
Image: "views/image"
|
||||
Image: "views/image",
|
||||
Button: "views/button",
|
||||
Player: "views/player"
|
||||
};
|
||||
|
||||
View.constructors = {
|
||||
|
@ -13,5 +13,6 @@ add_jslib(wModel/themeStorage.js lib/wModel/themeStorage ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/vocabulary.js lib/wModel/vocabulary ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/attributes.js lib/wModel/attributes ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/image.js lib/wModel/image ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/button.js lib/wModel/button ${MAGNUS_DIR} node)
|
||||
|
||||
add_subdirectory(proxy)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
var Page = require("../lib/wModel/page");
|
||||
var String = require("../lib/wModel/string");
|
||||
var Button = require("../lib/wModel/button");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
|
||||
@ -13,6 +14,16 @@ var TestPage = Page.inherit({
|
||||
var header = new String(this._address["+"](new Address(["message"])), "This is a test page");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
|
||||
this._button = new Button(this._address["+"](new Address(["testButton"])));
|
||||
this._button.setLabel("Push me");
|
||||
this._button.on("activated", this._onActivate, this);
|
||||
this.addItem(this._button, 1, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
},
|
||||
"_onActivate": function() {
|
||||
this.trigger("serviceMessage", "Button works!");
|
||||
this._button.setEnabled(false);
|
||||
setTimeout(this._button.setEnabled.bind(this._button, true), 3000);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -25,7 +25,7 @@ target_link_libraries(perturabo wSocket)
|
||||
target_link_libraries(perturabo wDispatcher)
|
||||
target_link_libraries(perturabo utils)
|
||||
target_link_libraries(perturabo wModel)
|
||||
target_link_libraries(perturabo wServerUtils)
|
||||
target_link_libraries(perturabo wDatabase)
|
||||
target_link_libraries(perturabo wServerUtils)
|
||||
|
||||
install(TARGETS perturabo RUNTIME DESTINATION bin)
|
||||
|
@ -86,11 +86,11 @@ void Perturabo::start()
|
||||
server->listen(8082);
|
||||
|
||||
cout << "Registering models..." << endl;
|
||||
attributes->registerModel(dispatcher, server);
|
||||
commands->registerModel(dispatcher, server);
|
||||
attributes->getRegistered(connector);
|
||||
commands->getRegistered(connector);
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
beg->second->registerModel(dispatcher, server);
|
||||
beg->second->getRegistered(connector);
|
||||
}
|
||||
|
||||
cout << "Opening and indexing databases..." << endl;
|
||||
@ -115,11 +115,11 @@ void Perturabo::stop()
|
||||
commands->enableCommand(W::String(u"clearDatabase"), false);
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
beg->second->unregisterModel();
|
||||
beg->second->getUnregistered();
|
||||
}
|
||||
|
||||
commands->unregisterModel();
|
||||
attributes->unregisterModel();
|
||||
commands->getUnregistered();
|
||||
attributes->getUnregistered();
|
||||
server->stop();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user