Added action state update flag to optimize dispatch action state update.

This commit is contained in:
and3md 2017-09-21 20:21:37 +02:00
parent b4330ab776
commit f12bb80030
2 changed files with 37 additions and 5 deletions

View File

@ -26,6 +26,20 @@ private import std.string;
private import std.conv; private import std.conv;
private import std.utf : toUTF32; private import std.utf : toUTF32;
/// Define when action need state update - optimization for high frequently uses actions
enum ActionStateUpdateFlag : uint {
/// action never change state so there is no need to search for dispatch action state request
never = 0,
/// dispatch action state change if action added to widget
inWidget = 1,
/// dispatch action state change if run from accelerator (keyboard)
inAccelerator = 2,
/// always dispatch action state change
always = inWidget | inAccelerator
}
/// Keyboard accelerator (key + modifiers) /// Keyboard accelerator (key + modifiers)
struct Accelerator { struct Accelerator {
/// Key code, usually one of KeyCode enum items /// Key code, usually one of KeyCode enum items
@ -301,6 +315,8 @@ class Action {
protected ActionState _defaultState = ACTION_STATE_ENABLED; protected ActionState _defaultState = ACTION_STATE_ENABLED;
protected uint _stateUpdateFlag = ActionStateUpdateFlag.always;
/// set default state to disabled, visible, not-checked /// set default state to disabled, visible, not-checked
Action disableByDefault() { _defaultState = ACTION_STATE_DISABLE; return this; } Action disableByDefault() { _defaultState = ACTION_STATE_DISABLE; return this; }
/// set default state to disabled, invisible, not-checked /// set default state to disabled, invisible, not-checked
@ -327,6 +343,15 @@ class Action {
return this; return this;
} }
/// return action state update flag (see ActionStateUpdateFlag for details)
@property uint stateUpdateFlag() const { return _stateUpdateFlag; }
/// sets action state update flag (see ActionStateUpdateFlag for details)
@property Action stateUpdateFlag(uint newStateUpdateFlag) {
_stateUpdateFlag = newStateUpdateFlag;
return this;
}
/// returns optional string parameter /// returns optional string parameter
@property string stringParam() const { @property string stringParam() const {
return _stringParam; return _stringParam;
@ -358,6 +383,7 @@ class Action {
_objectParam = v; _objectParam = v;
return this; return this;
} }
/// deep copy constructor /// deep copy constructor
this(immutable Action a) { this(immutable Action a) {
_id = a._id; _id = a._id;
@ -368,6 +394,7 @@ class Action {
_accelerators = a._accelerators.dup; _accelerators = a._accelerators.dup;
_stringParam = a._stringParam; _stringParam = a._stringParam;
_longParam = a._longParam; _longParam = a._longParam;
_stateUpdateFlag = a._stateUpdateFlag;
if (a._objectParam) if (a._objectParam)
_objectParam = cast(Object)a._objectParam; _objectParam = cast(Object)a._objectParam;
} }
@ -382,7 +409,8 @@ class Action {
_id = id; _id = id;
} }
/// create action with id, labelResourceId, and optional icon and key accelerator. /// create action with id, labelResourceId, and optional icon and key accelerator.
this(int id, string labelResourceId, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0) { this(int id, string labelResourceId, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0,
uint stateUpdateFlag = ActionStateUpdateFlag.always ) {
_id = id; _id = id;
_label.id = labelResourceId; _label.id = labelResourceId;
_iconId = iconResourceId; _iconId = iconResourceId;
@ -394,9 +422,10 @@ class Action {
} }
_accelerators ~= Accelerator(keyCode, keyFlags); _accelerators ~= Accelerator(keyCode, keyFlags);
} }
_stateUpdateFlag = stateUpdateFlag;
} }
/// action with accelerator, w/o label /// action with accelerator, w/o label
this(int id, uint keyCode, uint keyFlags = 0) { this(int id, uint keyCode, uint keyFlags = 0, uint stateUpdateFlag = ActionStateUpdateFlag.always) {
_id = id; _id = id;
version (OSX) { version (OSX) {
if (keyFlags & KeyFlag.Control) { if (keyFlags & KeyFlag.Control) {
@ -404,9 +433,11 @@ class Action {
} }
} }
_accelerators ~= Accelerator(keyCode, keyFlags); _accelerators ~= Accelerator(keyCode, keyFlags);
_stateUpdateFlag = stateUpdateFlag;
} }
/// action with label, icon, and accelerator /// action with label, icon, and accelerator
this(int id, dstring label, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0) { this(int id, dstring label, string iconResourceId = null, uint keyCode = 0, uint keyFlags = 0,
uint stateUpdateFlag = ActionStateUpdateFlag.always) {
_id = id; _id = id;
_label.value = label; _label.value = label;
_iconId = iconResourceId; _iconId = iconResourceId;
@ -418,6 +449,7 @@ class Action {
} }
_accelerators ~= Accelerator(keyCode, keyFlags); _accelerators ~= Accelerator(keyCode, keyFlags);
} }
_stateUpdateFlag = stateUpdateFlag;
} }
/// returs array of accelerators /// returs array of accelerators
@property Accelerator[] accelerators() { @property Accelerator[] accelerators() {

View File

@ -741,7 +741,7 @@ public:
} }
/// call to update state for action (if action is assigned for widget) /// call to update state for action (if action is assigned for widget)
void updateActionState(bool force = false) { void updateActionState(bool force = false) {
if (!_action) if (!_action || !(action.stateUpdateFlag & ActionStateUpdateFlag.inWidget))
return; return;
if (updateActionState(_action, force)) if (updateActionState(_action, force))
handleActionStateChanged(); handleActionStateChanged();
@ -1190,7 +1190,7 @@ public:
if (action !is null) { if (action !is null) {
//Log.d("Action found: ", action.id, " ", action.labelValue.id); //Log.d("Action found: ", action.id, " ", action.labelValue.id);
// update action state // update action state
if (updateActionState(action, true) && action is _action) if ((action.stateUpdateFlag & ActionStateUpdateFlag.inAccelerator) && updateActionState(action, true) && action is _action)
handleActionStateChanged(); handleActionStateChanged();
//run only enabled actions //run only enabled actions