Commit ba331526 authored by Stefan Majewsky's avatar Stefan Majewsky

Cleanup the mess that is interactorutils.{h,cpp}

Also, rename InteractorTrigger to Trigger, and change the data type of
the Trigger's serialization to QByteArray.

svn path=/trunk/KDE/kdegames/palapeli/; revision=1118466
parent 14fd4cc9
......@@ -15,12 +15,12 @@ set(palapeli_SRCS
engine/interactor.cpp
engine/interactors.cpp
engine/interactormanager.cpp
engine/interactorutils.cpp
engine/mergegroup.cpp
engine/piece.cpp
engine/piecevisuals.cpp
engine/scene.cpp
engine/texturehelper.cpp
engine/trigger.cpp
engine/view.cpp
engine/zoomwidget.cpp
file-io/collection.cpp
......
......@@ -18,6 +18,29 @@
#include "interactor.h"
#include <QGraphicsView>
//BEGIN events
Palapeli::MouseEvent::MouseEvent(QGraphicsView* view, const QPoint& pos_)
: pos(pos_)
, scenePos(view->mapToScene(pos_))
{
}
Palapeli::MouseEvent::MouseEvent()
{
}
Palapeli::WheelEvent::WheelEvent(QGraphicsView* view, const QPoint& pos_, int delta_)
: pos(pos_)
, scenePos(view->mapToScene(pos_))
, delta(delta_)
{
}
//END events
Palapeli::Interactor::Interactor(int priority, Palapeli::InteractorType type, QGraphicsView* view)
: m_type(type)
, m_view(view)
......
......@@ -19,21 +19,45 @@
#ifndef PALAPELI_INTERACTOR_H
#define PALAPELI_INTERACTOR_H
#include "interactorutils.h"
#include <QEvent>
#include <QGraphicsView>
class QGraphicsScene;
class QGraphicsView;
#include <QIcon>
#include <QMetaType>
namespace Palapeli
{
struct MouseEvent
{
public:
MouseEvent(QGraphicsView* view, const QPoint& pos);
QPoint pos;
QPointF scenePos;
protected:
friend class Interactor;
MouseEvent();
};
struct WheelEvent
{
public:
WheelEvent(QGraphicsView* view, const QPoint& pos, int delta);
QPoint pos;
QPointF scenePos;
int delta;
};
enum InteractorType
{
MouseInteractor = 1,
WheelInteractor = 2
};
enum EventProcessingFlag {
EventMatches = 1 << 0,
EventStartsInteraction = 1 << 1,
EventConcludesInteraction = 1 << 2
};
Q_DECLARE_FLAGS(EventProcessingFlags, EventProcessingFlag)
class Interactor
{
//TODO: add a flag for interactors which misbehave extremely with "NoButton;NoModifier" or "NoButton;*" triggers
......@@ -87,7 +111,6 @@ namespace Palapeli
int m_priority;
};
}
Q_DECLARE_METATYPE(Palapeli::Interactor*)
Q_DECLARE_OPERATORS_FOR_FLAGS(Palapeli::EventProcessingFlags)
#endif // PALAPELI_INTERACTOR_H
......@@ -36,7 +36,7 @@ Palapeli::InteractorManager::InteractorManager(QGraphicsView* view)
m_interactors["RubberBand"] = new Palapeli::RubberBandInteractor(view);
m_interactors["Constraints"] = new Palapeli::ConstraintInteractor(view);
//setup triggers
typedef Palapeli::InteractorTrigger PIT;
typedef Palapeli::Trigger PIT;
m_triggers << qMakePair(PIT("LeftButton;NoModifier"), m_interactors["MovePiece"]);
m_triggers << qMakePair(PIT("LeftButton;ControlModifier"), m_interactors["SelectPiece"]);
m_triggers << qMakePair(PIT("RightButton;NoModifier"), m_interactors["MoveViewport"]);
......@@ -64,7 +64,7 @@ void Palapeli::InteractorManager::handleEvent(QWheelEvent* event)
//convert event
Palapeli::WheelEvent pEvent(m_view, event->pos(), event->delta());
//try to handle event
foreach (const Palapeli::AssociatedInteractorTrigger& aTrigger, m_triggers)
foreach (const Palapeli::AssociatedTrigger& aTrigger, m_triggers)
if (testTrigger(aTrigger.first, event) & Palapeli::EventMatches)
aTrigger.second->sendEvent(pEvent);
}
......@@ -87,7 +87,7 @@ void Palapeli::InteractorManager::handleEvent(QMouseEvent* event)
m_mousePos = event->pos();
//check which triggers are activated by this event
QMap<Palapeli::Interactor*, EventContext> interactorData;
foreach (const Palapeli::AssociatedInteractorTrigger& trigger, m_triggers)
foreach (const Palapeli::AssociatedTrigger& trigger, m_triggers)
{
//NOTE: One interactor may have multiple triggers, so we OR stuff together.
const Palapeli::EventProcessingFlags flags = testTrigger(trigger.first, event);
......@@ -108,7 +108,7 @@ void Palapeli::InteractorManager::handleEvent(QKeyEvent* event)
Palapeli::MouseEvent pEvent(m_view, m_mousePos);
//check which triggers are activated by this event
QMap<Palapeli::Interactor*, EventContext> interactorData;
foreach (const Palapeli::AssociatedInteractorTrigger& trigger, m_triggers)
foreach (const Palapeli::AssociatedTrigger& trigger, m_triggers)
{
//NOTE: One interactor may have multiple triggers, so we OR all flags together.
interactorData[trigger.second].flags |= testTrigger(trigger.first, event);
......@@ -163,7 +163,7 @@ void Palapeli::InteractorManager::handleEventCommon(const Palapeli::MouseEvent&
}
}
Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Palapeli::InteractorTrigger& trigger, QWheelEvent* event)
Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Palapeli::Trigger& trigger, QWheelEvent* event)
{
if (trigger.isValid())
{
......@@ -177,7 +177,7 @@ Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Pa
return 0;
}
Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Palapeli::InteractorTrigger& trigger, QMouseEvent* event)
Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Palapeli::Trigger& trigger, QMouseEvent* event)
{
if (trigger.isValid())
{
......@@ -208,7 +208,7 @@ Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Pa
return 0;
}
Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Palapeli::InteractorTrigger& trigger, QKeyEvent* event)
Palapeli::EventProcessingFlags Palapeli::InteractorManager::testTrigger(const Palapeli::Trigger& trigger, QKeyEvent* event)
{
if (trigger.isValid())
{
......@@ -244,12 +244,12 @@ const QList<Palapeli::Interactor*> Palapeli::InteractorManager::interactors() co
return m_interactors.values();
}
const QList<Palapeli::AssociatedInteractorTrigger> Palapeli::InteractorManager::triggers() const
const QList<Palapeli::AssociatedTrigger> Palapeli::InteractorManager::triggers() const
{
return m_triggers;
}
void Palapeli::InteractorManager::setTriggers(const QList<Palapeli::AssociatedInteractorTrigger>& triggers)
void Palapeli::InteractorManager::setTriggers(const QList<Palapeli::AssociatedTrigger>& triggers)
{
foreach (Palapeli::Interactor* interactor, m_interactors)
interactor->setInactive();
......
......@@ -19,7 +19,8 @@
#ifndef PALAPELI_INTERACTORMANAGER_H
#define PALAPELI_INTERACTORMANAGER_H
#include "interactorutils.h"
#include "interactor.h"
#include "trigger.h"
#include <QEvent>
#include <QGraphicsView>
......@@ -27,6 +28,8 @@
namespace Palapeli
{
typedef QPair<Palapeli::Trigger, Palapeli::Interactor*> AssociatedTrigger;
class InteractorManager : public QObject
{
public:
......@@ -40,12 +43,12 @@ namespace Palapeli
///\note This list will never change at run-time.
const QList<Palapeli::Interactor*> interactors() const;
const QList<Palapeli::AssociatedInteractorTrigger> triggers() const;
void setTriggers(const QList<Palapeli::AssociatedInteractorTrigger>& triggers);
const QList<Palapeli::AssociatedTrigger> triggers() const;
void setTriggers(const QList<Palapeli::AssociatedTrigger>& triggers);
protected:
Palapeli::EventProcessingFlags testTrigger(const Palapeli::InteractorTrigger& trigger, QWheelEvent* event);
Palapeli::EventProcessingFlags testTrigger(const Palapeli::InteractorTrigger& trigger, QMouseEvent* event);
Palapeli::EventProcessingFlags testTrigger(const Palapeli::InteractorTrigger& trigger, QKeyEvent* event);
Palapeli::EventProcessingFlags testTrigger(const Palapeli::Trigger& trigger, QWheelEvent* event);
Palapeli::EventProcessingFlags testTrigger(const Palapeli::Trigger& trigger, QMouseEvent* event);
Palapeli::EventProcessingFlags testTrigger(const Palapeli::Trigger& trigger, QKeyEvent* event);
struct EventContext
{
......@@ -57,7 +60,7 @@ namespace Palapeli
QGraphicsView* m_view;
QMap<QByteArray, Palapeli::Interactor*> m_interactors; //NOTE: The interactor list is always hard-coded, based on what is available. The keys are used for writing the trigger list to the config.
//configuration
QList<Palapeli::AssociatedInteractorTrigger> m_triggers;
QList<Palapeli::AssociatedTrigger> m_triggers;
//state
Qt::MouseButtons m_buttons;
QPoint m_mousePos;
......
......@@ -16,59 +16,85 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
***************************************************************************/
#include "interactorutils.h"
#include "trigger.h"
#include <QGraphicsView>
#include <QMap>
#include <KGlobal>
#include <KLocalizedString>
//BEGIN events
Palapeli::MouseEvent::MouseEvent(QGraphicsView* view, const QPoint& pos_)
: pos(pos_)
, scenePos(view->mapToScene(pos_))
{
}
Palapeli::MouseEvent::MouseEvent()
{
}
Palapeli::WheelEvent::WheelEvent(QGraphicsView* view, const QPoint& pos_, int delta_)
: pos(pos_)
, scenePos(view->mapToScene(pos_))
, delta(delta_)
namespace
{
}
class ByteArrayList : public QList<QByteArray>
{
public:
QByteArray join(const QChar& separator) const
{
char sep = separator.toLatin1();
if (isEmpty())
return QByteArray();
int size = -1;
for (int i = 0; i < count(); ++i)
size += 1 + at(i).size();
QByteArray result;
result.reserve(size);
for (int i = 0; i < count(); ++i)
{
if (i != 0)
result.append(sep);
result.append(at(i));
}
return result;
}
};
template<typename T, typename ListType> struct TriggerData
{
QMap<Qt::KeyboardModifier, T> m_modifierStrings;
QMap<Qt::MouseButton, T> m_buttonStrings;
QMap<Qt::Orientation, T> m_orientationStrings;
//END events
T modifierString(Qt::KeyboardModifiers modifiers, const QChar& separator) const
{
typename QMap<Qt::KeyboardModifier, T>::const_iterator it1 = m_modifierStrings.begin(), it2 = m_modifierStrings.end();
ListType modifierStrings;
for (; it1 != it2; ++it1)
if (modifiers & it1.key())
modifierStrings << it1.value();
return modifierStrings.join(separator);
}
struct Palapeli::InteractorTrigger::Data
{
QMap<Qt::KeyboardModifier, QString> m_modifierStrings;
QMap<Qt::MouseButton, QString> m_buttonStrings;
QMap<Qt::Orientation, QString> m_orientationStrings;
T actionString(Qt::Orientation wheelDirection, Qt::MouseButton button) const
{
if (m_orientationStrings.contains(wheelDirection))
return m_orientationStrings.value(wheelDirection);
else
return m_buttonStrings.value(button);
}
};
Data(bool machineReadableStrings)
struct TriggerParserData : public TriggerData<QByteArray, ByteArrayList>
{
if (machineReadableStrings)
TriggerParserData()
{
m_modifierStrings[Qt::ShiftModifier] = QLatin1String("ShiftModifier");
m_modifierStrings[Qt::ControlModifier] = QLatin1String("ControlModifier");
m_modifierStrings[Qt::AltModifier] = QLatin1String("AltModifier");
m_modifierStrings[Qt::MetaModifier] = QLatin1String("MetaModifier");
m_modifierStrings[Qt::GroupSwitchModifier] = QLatin1String("GroupSwitchModifier");
m_buttonStrings[Qt::NoButton] = QLatin1String("NoButton");
m_buttonStrings[Qt::LeftButton] = QLatin1String("LeftButton");
m_buttonStrings[Qt::RightButton] = QLatin1String("RightButton");
m_buttonStrings[Qt::MidButton] = QLatin1String("MidButton");
m_buttonStrings[Qt::XButton1] = QLatin1String("XButton1");
m_buttonStrings[Qt::XButton2] = QLatin1String("XButton2");
m_orientationStrings[Qt::Horizontal] = QLatin1String("wheel:Horizontal");
m_orientationStrings[Qt::Vertical] = QLatin1String("wheel:Vertical");
m_modifierStrings[Qt::ShiftModifier] = "ShiftModifier";
m_modifierStrings[Qt::ControlModifier] = "ControlModifier";
m_modifierStrings[Qt::AltModifier] = "AltModifier";
m_modifierStrings[Qt::MetaModifier] = "MetaModifier";
m_modifierStrings[Qt::GroupSwitchModifier] = "GroupSwitchModifier";
m_buttonStrings[Qt::NoButton] = "NoButton";
m_buttonStrings[Qt::LeftButton] = "LeftButton";
m_buttonStrings[Qt::RightButton] = "RightButton";
m_buttonStrings[Qt::MidButton] = "MidButton";
m_buttonStrings[Qt::XButton1] = "XButton1";
m_buttonStrings[Qt::XButton2] = "XButton2";
m_orientationStrings[Qt::Horizontal] = "wheel:Horizontal";
m_orientationStrings[Qt::Vertical] = "wheel:Vertical";
}
else
};
struct TriggerPrinterData : public TriggerData<QString, QStringList>
{
TriggerPrinterData()
{
//FIXME: These are probably wrong for Macs.
m_modifierStrings[Qt::ShiftModifier] = i18nc("a keyboard modifier", "Shift");
......@@ -87,34 +113,31 @@ struct Palapeli::InteractorTrigger::Data
m_orientationStrings[Qt::Horizontal] = i18n("Horizontal-Scroll");
m_orientationStrings[Qt::Vertical] = i18n("Vertical-Scroll");
}
}
};
K_GLOBAL_STATIC_WITH_ARGS(Palapeli::InteractorTrigger::Data, itParserData, (true))
K_GLOBAL_STATIC_WITH_ARGS(Palapeli::InteractorTrigger::Data, itPrettyData, (false))
};
}
//BEGIN Palapeli::InteractorTrigger
K_GLOBAL_STATIC(TriggerParserData, tParserData)
K_GLOBAL_STATIC(TriggerPrinterData, tPrinterData)
Palapeli::InteractorTrigger::InteractorTrigger()
Palapeli::Trigger::Trigger()
: m_button((Qt::MouseButton) -1)
{
}
Palapeli::InteractorTrigger::InteractorTrigger(const QString& serialization)
Palapeli::Trigger::Trigger(const QByteArray& serialization)
{
const Palapeli::InteractorTrigger::Data& data = *itParserData;
//expect format "BUTTON_OR_WHEEL;MODIFIERLIST", i.e. two sections separated by semicolon
const QStringList sections = serialization.split(';');
const QList<QByteArray> sections = serialization.split(';');
if (sections.size() != 2)
return;
//parse modifier list (separated by vertical pipes) -> We do this first because this one can fail.
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
if (sections[1] != QLatin1String("NoModifier"))
if (sections[1] != "NoModifier")
{
const QStringList modifierStrings = sections[1].split('|');
foreach (const QString& modifierString, modifierStrings)
const QList<QByteArray> modifierStrings = sections[1].split('|');
foreach (const QByteArray& modifierString, modifierStrings)
{
Qt::KeyboardModifier modifier = data.m_modifierStrings.key(modifierString, Qt::NoModifier);
Qt::KeyboardModifier modifier = tParserData->m_modifierStrings.key(modifierString, Qt::NoModifier);
if (modifier == Qt::NoModifier)
return; //parsing failed
modifiers |= modifier;
......@@ -122,29 +145,11 @@ Palapeli::InteractorTrigger::InteractorTrigger(const QString& serialization)
}
m_modifiers = modifiers;
//parse first section (button or wheel direction) -> default to NoButton + NoOrientation if parsing fails
m_button = data.m_buttonStrings.key(sections[0], Qt::NoButton);
m_wheelDirection = data.m_orientationStrings.key(sections[0], (Qt::Orientation) 0);
}
QPair<QString, QStringList> Palapeli::InteractorTrigger::toStringGeneric(const Palapeli::InteractorTrigger::Data& data) const
{
//find modifier strings
QStringList modifierStrings;
QMap<Qt::KeyboardModifier, QString>::const_iterator it1 = data.m_modifierStrings.begin(), it2 = data.m_modifierStrings.end();
for (; it1 != it2; ++it1)
if (m_modifiers & it1.key())
modifierStrings << it1.value();
//write wheel direction or mouse button
QString actionString;
if (data.m_orientationStrings.contains(m_wheelDirection))
actionString = data.m_orientationStrings[m_wheelDirection];
else
actionString = data.m_buttonStrings[m_button];
//pass result bits to caller
return qMakePair(actionString, modifierStrings);
m_button = tParserData->m_buttonStrings.key(sections[0], Qt::NoButton);
m_wheelDirection = tParserData->m_orientationStrings.key(sections[0], (Qt::Orientation) 0);
}
bool Palapeli::InteractorTrigger::isValid() const
bool Palapeli::Trigger::isValid() const
{
if (m_wheelDirection > 0 && m_button > 0)
return false; //do not allow wheel and mouse triggers at the same time
......@@ -152,74 +157,64 @@ bool Palapeli::InteractorTrigger::isValid() const
return m_button >= 0; //do not allow negative m_button values
}
QString Palapeli::InteractorTrigger::serialized() const
QByteArray Palapeli::Trigger::serialized() const
{
if (!isValid())
return QString();
QPair<QString, QStringList> bits = toStringGeneric(*itParserData);
if (bits.second.isEmpty())
bits.second << QLatin1String("NoModifier");
return bits.first + QChar(';') + bits.second.join(QChar('|'));
return QByteArray();
const QByteArray actionString = tParserData->actionString(m_wheelDirection, m_button);
QByteArray modifierString = tParserData->modifierString(m_modifiers, '|');
if (modifierString.isEmpty())
modifierString = "NoModifier";
return actionString + QByteArray(1, ';') + modifierString;
}
QString Palapeli::InteractorTrigger::toString() const
QString Palapeli::Trigger::toString() const
{
const QPair<QString, QStringList> bits = toStringGeneric(*itPrettyData);
if (bits.second.isEmpty())
return bits.first;
const QString actionString = tPrinterData->actionString(m_wheelDirection, m_button);
const QString modifierString = tPrinterData->modifierString(m_modifiers, '|');
if (modifierString.isEmpty())
return actionString;
else
return bits.second.join(QChar('+')) + '+' + bits.first;
return modifierString + QChar('+') + actionString;
}
Qt::KeyboardModifiers Palapeli::InteractorTrigger::modifiers() const
Qt::KeyboardModifiers Palapeli::Trigger::modifiers() const
{
return m_modifiers;
}
void Palapeli::InteractorTrigger::setModifiers(Qt::KeyboardModifiers modifiers)
void Palapeli::Trigger::setModifiers(Qt::KeyboardModifiers modifiers)
{
m_modifiers = modifiers;
}
Qt::MouseButton Palapeli::InteractorTrigger::button() const
Qt::MouseButton Palapeli::Trigger::button() const
{
return m_button;
}
void Palapeli::InteractorTrigger::setButton(Qt::MouseButton button)
void Palapeli::Trigger::setButton(Qt::MouseButton button)
{
m_button = button;
if (m_button != Qt::NoButton)
m_wheelDirection = (Qt::Orientation) 0;
}
Qt::Orientation Palapeli::InteractorTrigger::wheelDirection() const
Qt::Orientation Palapeli::Trigger::wheelDirection() const
{
return m_wheelDirection;
}
void Palapeli::InteractorTrigger::setWheelDirection(Qt::Orientation orientation)
void Palapeli::Trigger::setWheelDirection(Qt::Orientation orientation)
{
m_wheelDirection = orientation;
if (m_wheelDirection != (Qt::Orientation) 0)
m_button = Qt::NoButton;
}
bool Palapeli::InteractorTrigger::operator==(const Palapeli::InteractorTrigger& other) const
bool Palapeli::Trigger::operator==(const Palapeli::Trigger& other) const
{
return m_modifiers == other.m_modifiers
&& m_button == other.m_button
&& m_wheelDirection == other.m_wheelDirection;
}
//END Palapeli::InteractorTrigger
QList<Qt::MouseButton> Palapeli::analyzeFlags(Qt::MouseButtons buttons)
{
const QList<Qt::MouseButton>& knownButtons = itParserData->m_buttonStrings.keys();
QList<Qt::MouseButton> result;
foreach (Qt::MouseButton button, knownButtons)
if (buttons & button)
result << button;
return result;
}
......@@ -16,61 +16,30 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
***************************************************************************/
#ifndef PALAPELI_INTERACTORUTILS_H
#define PALAPELI_INTERACTORUTILS_H
#ifndef PALAPELI_TRIGGER_H
#define PALAPELI_TRIGGER_H
class QGraphicsView;
#include <QMetaType>
#include <QPair>
#include <QPointF>
#include <QString>
namespace Palapeli
{
struct MouseEvent
{
public:
MouseEvent(QGraphicsView* view, const QPoint& pos);
QPoint pos;
QPointF scenePos;
protected:
friend class Interactor;
MouseEvent();
};
struct WheelEvent
{
public:
WheelEvent(QGraphicsView* view, const QPoint& pos, int delta);
QPoint pos;
QPointF scenePos;
int delta;
};
QList<Qt::MouseButton> analyzeFlags(Qt::MouseButtons buttons);
struct InteractorTrigger
struct Trigger
{
public:
///Constructs an invalid trigger. (The mouse button is set to -1.)
InteractorTrigger();
Trigger();
///Constructs a trigger from the given serialization. If the parsing fails, this constructor returns an invalid trigger (just like the default constructor).
///Possible serializations include "MidButton;NoModifier", "RightButton;ShiftModifier" and "wheel:Horizontal;ShiftModifier|ControlModifier". (A formal specification of the format is left as an exercise to the reader.)
InteractorTrigger(const QString& serialization); //krazy:exclude=explicit (I want implicit conversions)
Trigger(const QByteArray& serialization); //krazy:exclude=explicit (I want implicit conversions)
///Returns whether this triger is valid.
bool isValid() const;
///Returns the serialization for this trigger, or an empty string if this trigger is invalid.
///\see isValid()
QString serialized() const;
QByteArray serialized() const;
///Returns a translated (i.e. user-compatible) string representation for this trigger. This representation is not suitable for machine-readable files, use serialized() instead.
QString toString() const;
///\internal
struct Data;
///\internal
QPair<QString, QStringList> toStringGeneric(const Data& data) const;
Qt::KeyboardModifiers modifiers() const;
void setModifiers(Qt::KeyboardModifiers modifiers);
Qt::MouseButton button() const; ///< Returns 0 by default or when a trigger wheel direction has been set.
......@@ -78,31 +47,18 @@ namespace Palapeli
Qt::Orientation wheelDirection() const; ///< Returns 0 by default or when a trigger button has been set.
void setWheelDirection(Qt::Orientation orientation); ///< Setting this will reset button().
bool operator==(const Palapeli::InteractorTrigger& other) const;
inline bool operator!=(const Palapeli::InteractorTrigger& other) const;
bool operator==(const Palapeli::Trigger& other) const;
inline bool operator!=(const Palapeli::Trigger& other) const;
private:
Qt::KeyboardModifiers m_modifiers;
Qt::MouseButton m_button;
Qt::Orientation m_wheelDirection;
};
class Interactor;
typedef QPair<Palapeli::InteractorTrigger, Palapeli::Interactor*> AssociatedInteractorTrigger;