MuseScore/src/framework/actions/internal/actionsdispatcher.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

95 lines
2.9 KiB
C++
Raw Normal View History

/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2020-06-08 15:55:01 +02:00
#include "actionsdispatcher.h"
#include "log.h"
#include "actionable.h"
2020-06-08 15:55:01 +02:00
using namespace mu::actions;
2020-08-27 14:47:18 +02:00
ActionsDispatcher::~ActionsDispatcher()
2020-06-08 15:55:01 +02:00
{
2020-08-27 14:47:18 +02:00
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
Clients& clients = it->second;
for (auto cit = clients.begin(); cit != clients.end(); ++cit) {
Actionable* client = cit->first;
client->setDispatcher(nullptr);
}
}
2020-06-08 15:55:01 +02:00
}
void ActionsDispatcher::dispatch(const ActionCode& actionCode)
2020-06-08 15:55:01 +02:00
{
static ActionData dummy;
dispatch(actionCode, dummy);
2020-06-08 15:55:01 +02:00
}
void ActionsDispatcher::dispatch(const ActionCode& actionCode, const ActionData& data)
2020-06-08 15:55:01 +02:00
{
auto it = m_clients.find(actionCode);
if (it == m_clients.end()) {
LOGW() << "not registred action: " << actionCode;
2020-06-08 15:55:01 +02:00
return;
}
2020-06-19 13:49:23 +02:00
int canReceiveCount = 0;
const Clients& clients = it->second;
for (auto cit = clients.cbegin(); cit != clients.cend(); ++cit) {
const Actionable* client = cit->first;
if (client->canReceiveAction(actionCode)) {
2020-06-19 13:49:23 +02:00
++canReceiveCount;
const CallBacks& callbacks = cit->second;
auto cbit = callbacks.find(actionCode);
IF_ASSERT_FAILED(cbit != callbacks.end()) {
continue;
}
const ActionCallBackWithNameAndData& callback = cbit->second;
LOGI() << "try call action: " << actionCode;
callback(actionCode, data);
}
}
2020-06-19 13:49:23 +02:00
if (canReceiveCount == 0) {
LOGI() << "no one can handle the action: " << actionCode;
2020-06-19 13:49:23 +02:00
} else if (canReceiveCount > 1) {
LOGW() << "More than one client can handle the action, this is not a typical situation.";
}
2020-06-08 15:55:01 +02:00
}
void ActionsDispatcher::unReg(Actionable* client)
2020-06-08 15:55:01 +02:00
{
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
Clients& clients = it->second;
clients.erase(client);
2020-06-08 15:55:01 +02:00
}
2020-08-27 14:47:18 +02:00
client->setDispatcher(nullptr);
2020-06-08 15:55:01 +02:00
}
void ActionsDispatcher::reg(Actionable* client, const ActionCode& actionCode, const ActionCallBackWithNameAndData& call)
2020-06-08 15:55:01 +02:00
{
client->setDispatcher(this);
Clients& clients = m_clients[actionCode];
CallBacks& callbacks = clients[client];
callbacks.insert({ actionCode, call });
2020-06-08 15:55:01 +02:00
}