如何避免在C中使用循环依赖项编码UNDO / REDO?

时间:2019-05-24 00:33:35

标签: c dependencies code-organization

///我将此注释移到顶部:我正在使用结构和相关方法(如int MyClass_getInt(MyClass * this))重新创建OOP

我正在用C编写一个小型DAW。在Timeline.h中有我的时间轴 Region 类。我希望我的 UndoRedoStack 类能够与多个 Timeline 实例一起使用,所以我希望 UndoRedoStack 位于单独的.c中/.h文件。

这种思路似乎要求 TimelineUndoRedoCommand 类了解时间轴区域,因为它需要备份先前存在的状态。

还需要时间轴来了解 TimelineUndoRedoCommand ,以便可以将它们触发到 UndoRedoStack 中。

这似乎是循环依赖。我应该如何构造它们,以便避免循环依赖?

// 我最终要求Timeline.h编写所有需要它的代码,但是像这样单独存放UndoRedo:

/*

    UndoRedoCmd

 */

typedef struct _UndoRedoCmd{
    void* content;
    char* name;
}UndoRedoCmd;

/*

    UndoRedoStack

 */

typedef struct _UndoRedoStack{
    t_LinkList* undoStack;
    t_LinkList* redoStack;
    bool redoingNow;
    void (*redoFunc)(UndoRedoCmd* redoThis);
    void (*undoFunc)(UndoRedoCmd* undoThis);
}UndoRedoStack;

/*
 UndoRedoCmd
 */


UndoRedoCmd* UndoRedoCmd_New(char* name, void* content){
    UndoRedoCmd*  this = malloc(sizeof(UndoRedoCmd));
    this->name=name;
    this->content=content;
    return this;
}


void UndoRedoCmd_Kill(UndoRedoCmd* this){
    /*this should never be used.  instead the
     user of UndoRedoStack should provide
     a custom killer which simply calls
     free after freeing the contents
     */
}


/*
 UndoRedoStack
 */

UndoRedoStack* UndoRedoStack_New(
                                 void (*redoFunc)(UndoRedoCmd*),
                                 void (*undoFunc)(UndoRedoCmd*),
                                 void (*freeLinkFunction)(void*)
                                 ){

    /*
     redoFunc is meant to take the content of the command and redo some action with it.
     undoFunc is the opposite
     freeLinkFunction is meant should free a LinkList_Link with the custom UndoRedo content inside of it.
     */


    UndoRedoStack* this = malloc(sizeof(UndoRedoStack));
    this->undoFunc=undoFunc;
    this->redoFunc=redoFunc;

    this->redoStack = LinkList_New();
    this->redoStack->autoFree=2;
    this->redoStack->customFree=freeLinkFunction;

    this->undoStack = LinkList_New();
    this->undoStack->autoFree=2;
    this->undoStack->customFree=freeLinkFunction;

    return this;


}

void UndoRedoStack_Kill(UndoRedoStack* this){

    LinkList_Free(this->undoStack);
    LinkList_Free(this->redoStack);

    free(this);
}


void UndoRedoStack_do(UndoRedoStack* this,char* name,void* undoredoinfo){
    UndoRedoCmd* mycmd = UndoRedoCmd_New(name, undoredoinfo);
    LinkList_push(this->undoStack, mycmd);

}

void UndoRedoStack_undo(UndoRedoStack* this){
    if(this->undoStack->length==0){
        return;
    }

    UndoRedoCmd* undoMe = (UndoRedoCmd*)LinkList_pop(this->undoStack);
    this->undoFunc(undoMe);
    LinkList_push(this->redoStack, undoMe);
}

void UndoRedoStack_redo(UndoRedoStack* this){

    if(this->redoStack->length==0){
        return;
    }

    UndoRedoCmd* redoMe = (UndoRedoCmd*)LinkList_pop(this->redoStack);
    this->redoFunc(redoMe);
    LinkList_push(this->undoStack, redoMe);
}

0 个答案:

没有答案