简体   繁体   English

命令模式:如何执行连续动作? (例如,移动物体)

[英]Command pattern: how can I do continuous actions? (e.g. moving an object)

Suppose that I'm making a program where user can draw and then move shapes around. 假设我正在编写一个程序,用户可以在其中绘制然后移动形状。 MoveCommand then can look something like this: 然后, MoveCommand可能如下所示:

class MoveCommand {
public:
    MoveCommand(Shape& shape, const Vector2f& offset) :
            shape(shape), offset(offset)
    { }

    void execute() {
        shape.move(offset);
    } 

    void undo() {
        shape.move(-offset);
    }
private:
    Shape& shape;
    Vector2f offset;
};

This works well, but how can I display preview of movement (when user holds mouse button) and then only store final offset on mouse button release? 这很好用,但是如何显示运动预览(当用户按住鼠标按钮时),然后仅在释放鼠标按钮时存储最终偏移量?

Should ShapeEditor class move the shape and then create MoveCommand on button release? ShapeEditor类是否应该移动形状,然后在释放按钮时创建MoveCommand What if the code of execute() is not trivial? 如果execute()的代码不简单怎么办? How can I avoid code duplication in ShapeEditor and MoveCommand ? 如何避免ShapeEditorMoveCommand代码重复?

This works well, but how can I display preview of movement (when user holds mouse button) and then only store final offset on mouse button release? 这很好用,但是如何显示运动预览(当用户按住鼠标按钮时),然后仅在释放鼠标按钮时存储最终偏移量?

If I understand you correctly, you want to make the whole movement un-doable / re-doable as a single operation, while animating each individual micro-movement when it's done interactively the first time. 如果我对您的理解正确,那么您想使整个运动无法执行/只能重新执行,同时在首次交互完成时为每个微动动动画。

One way to do it is what you suggest yourself, that is recording the undo / redo command only when the movement is complete. 一种解决方法是您自己建议,即仅在移动完成后才记录undo / redo命令。 As you point out, that leads to some code duplication. 如您所指出,这会导致某些代码重复。 In practice that's not a problem, as you can always factor that common code out. 实际上,这不是问题,因为您可以随时将这些通用代码排除在外。

Another way is to create a MoveCommand for every micro-movement and then implement command merging as part of your undo / redo stack. 另一种方法是为每个微动创建一个MoveCommand,然后将命令合并作为撤消/重做堆栈的一部分。 See how it's done in Qt . 查看如何在Qt中完成

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何实例化对象并让它们在 scope 之外仍然可用? (例如在循环中实例化一个 object) - How do I instantiate objects and have them still be available outside of their scope? (e.g. instantiated an object in a loop) 如何使用模板 arguments 的特定格式定义 class 模板? 例如:Fn(Args…) - How do I define a class template with specfic format of taking template arguments? e.g.: Fn(Args…) 如何添加成员 function 作为例如 Boost Log 过滤器? - How do I add a member function as e.g. Boost Log filter? 如何从boost库中取出单个元素(例如shared_pointer)? - How can I take a single element out of a boost library (e.g. shared_pointer)? 如何加速此代码(MWE!),例如使用限制 - How can I accelerate this code (MWE!), e.g. using restrict 终端如何在shell提示符下以编程方式阻止退格键,以便不能在其上退格键,例如$表示bash或C:\\ blah \\> - How do terminals programmatically block the backspace at a shell prompt so you can't backspace over it, e.g. $ for bash or C:\blah\> 如何访问(例如,cout)多维 STL 向量中的迭代器的当前值(C++) - how do I access (e.g., cout) the current value of iterators in multi-dimensional STL vectors (C++) 我如何在Linux性能下获得libc6符号(例如_int_malloc)的致电父母? - How do I get call parents for libc6 symbols (e.g. _int_malloc) with linux perf? 当播放器在多行文本框中更改文本 cursor position 时,我如何调用代码(例如函数)? - How can I have code called (e.g., a function) when the player changes text cursor position in a multiline text box? 我如何从类外部(例如,通过另一个类)使用与boosed_graph有关的模板化typedef,即_in_一个类 - How can I use templated typedefs, that are _in_ a class, from outside the class (e.g. by another class), in relation to boost::graph
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM