// Я перемещаю эту заметку наверх: я воссоздаю ООП со структурами и связанными методами, такими как int MyClass_getInt (MyClass * this)
Я пишу небольшую DAW в C. У меня есть классы Timeline и Region в Timeline.h. Я бы хотел, чтобы мой класс 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);
}