redo threading in PreviewModel so that you don't have to wait for everything to load to quit, and the threads don't access any of PreviewModel's data

This commit is contained in:
jacob1 2013-07-10 14:53:35 -04:00
parent 6e7a5488b5
commit 4f6904b1ed
2 changed files with 121 additions and 139 deletions

View File

@ -7,91 +7,52 @@
PreviewModel::PreviewModel(): PreviewModel::PreviewModel():
save(NULL), save(NULL),
saveComments(NULL), saveComments(NULL),
saveData(NULL),
doOpen(false), doOpen(false),
updateSaveDataWorking(false),
updateSaveDataFinished(false),
updateSaveInfoWorking(false),
updateSaveInfoFinished(false),
updateSaveCommentsWorking(false),
updateSaveCommentsFinished(false),
commentsTotal(0), commentsTotal(0),
commentsPageNumber(1), commentsPageNumber(1),
commentBoxEnabled(false) commentBoxEnabled(false),
updateSaveDataInfo(NULL),
updateSaveInfoInfo(NULL),
updateSaveCommentsInfo(NULL)
{ {
} }
void * PreviewModel::updateSaveInfoTHelper(void * obj) void * PreviewModel::updateSaveInfoT(void * obj)
{ {
return ((PreviewModel*)obj)->updateSaveInfoT(); SaveInfo * tempSave = Client::Ref().GetSave(((threadInfo*)obj)->saveID, ((threadInfo*)obj)->saveDate);
} ((threadInfo*)obj)->threadFinished = true;
if (((threadInfo*)obj)->previewExited)
void * PreviewModel::updateSaveDataTHelper(void * obj) delete tempSave;
{
return ((PreviewModel*)obj)->updateSaveDataT();
}
void * PreviewModel::updateSaveCommentsTHelper(void * obj)
{
return ((PreviewModel*)obj)->updateSaveCommentsT();
}
void PreviewModel::updateSaveInfoTDelete(void * arg)
{
delete arg;
}
void PreviewModel::updateSaveDataTDelete(void * arg)
{
free(arg);
}
void PreviewModel::updateSaveCommentsTDelete(void * arg)
{
for(int i = 0; i < ((std::vector<SaveComment*> *)arg)->size(); i++)
delete ((std::vector<SaveComment*> *)arg)->at(i);
((std::vector<SaveComment*> *)arg)->clear();
delete arg;
}
void * PreviewModel::updateSaveInfoT()
{
SaveInfo * tempSave;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
tempSave = Client::Ref().GetSave(tSaveID, tSaveDate);
pthread_cleanup_push(&updateSaveInfoTDelete,tempSave);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_testcancel();
updateSaveInfoFinished = true;
pthread_cleanup_pop(0);
return tempSave; return tempSave;
} }
void * PreviewModel::updateSaveDataT() void * PreviewModel::updateSaveDataT(void * obj)
{ {
int tempDataSize; int tempDataSize;
unsigned char * tempData; unsigned char * tempData = Client::Ref().GetSaveData(((threadInfo*)obj)->saveID, ((threadInfo*)obj)->saveDate, tempDataSize);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); SaveData * tempSave = new SaveData(tempData, tempDataSize);
tempData = Client::Ref().GetSaveData(tSaveID, tSaveDate, tempDataSize); ((threadInfo*)obj)->threadFinished = true;
pthread_cleanup_push(&updateSaveDataTDelete,tempData); if (((threadInfo*)obj)->previewExited)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); {
pthread_testcancel(); delete tempSave;
saveDataBuffer.clear(); free(tempData);
if (tempData) }
saveDataBuffer.insert(saveDataBuffer.begin(), tempData, tempData+tempDataSize); return tempSave;
updateSaveDataFinished = true;
pthread_cleanup_pop(1);
return NULL;
} }
void * PreviewModel::updateSaveCommentsT() void * PreviewModel::updateSaveCommentsT(void * obj)
{ {
std::vector<SaveComment*> * tempComments; std::vector<SaveComment*> * tempComments = Client::Ref().GetComments(((threadInfo*)obj)->saveID, (((threadInfo*)obj)->saveDate-1)*20, 20); //saveDate is used as commentsPageNumber
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); ((threadInfo*)obj)->threadFinished = true;
tempComments = Client::Ref().GetComments(tSaveID, (commentsPageNumber-1)*20, 20); if (((threadInfo*)obj)->previewExited)
pthread_cleanup_push(&updateSaveCommentsTDelete,tempComments); {
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); for(int i = 0; i < tempComments->size(); i++)
pthread_testcancel(); delete tempComments->at(i);
updateSaveCommentsFinished = true; tempComments->clear();
pthread_cleanup_pop(0); delete tempComments;
}
return tempComments; return tempComments;
} }
@ -133,7 +94,13 @@ void PreviewModel::UpdateSave(int saveID, int saveDate)
delete save; delete save;
save = NULL; save = NULL;
} }
saveDataBuffer.clear(); if (saveData)
{
if (saveData->data)
free(saveData->data);
delete saveData;
saveData = NULL;
}
if(saveComments) if(saveComments)
{ {
for(int i = 0; i < saveComments->size(); i++) for(int i = 0; i < saveComments->size(); i++)
@ -145,26 +112,29 @@ void PreviewModel::UpdateSave(int saveID, int saveDate)
notifySaveChanged(); notifySaveChanged();
notifySaveCommentsChanged(); notifySaveCommentsChanged();
if(!updateSaveDataWorking) if (!updateSaveDataInfo)
updateSaveDataInfo = new threadInfo(saveID, saveDate);
if (updateSaveDataInfo->threadFinished)
{ {
updateSaveDataWorking = true; updateSaveDataInfo->threadFinished = false;
updateSaveDataFinished = false; pthread_create(&updateSaveDataThread, 0, &PreviewModel::updateSaveDataT, updateSaveDataInfo);
pthread_create(&updateSaveDataThread, 0, &PreviewModel::updateSaveDataTHelper, this);
} }
if(!updateSaveInfoWorking) if (!updateSaveInfoInfo)
updateSaveInfoInfo = new threadInfo(saveID, saveDate);
if(updateSaveInfoInfo->threadFinished)
{ {
updateSaveInfoWorking = true; updateSaveInfoInfo->threadFinished = false;
updateSaveInfoFinished = false; pthread_create(&updateSaveInfoThread, 0, &PreviewModel::updateSaveInfoT, updateSaveInfoInfo);
pthread_create(&updateSaveInfoThread, 0, &PreviewModel::updateSaveInfoTHelper, this);
} }
if(!updateSaveCommentsWorking) if (!updateSaveCommentsInfo)
updateSaveCommentsInfo = new threadInfo(saveID, commentsPageNumber);
if (updateSaveCommentsInfo->threadFinished)
{ {
commentsLoaded = false; commentsLoaded = false;
updateSaveCommentsWorking = true; updateSaveCommentsInfo->threadFinished = false;
updateSaveCommentsFinished = false; pthread_create(&updateSaveCommentsThread, 0, &PreviewModel::updateSaveCommentsT, updateSaveCommentsInfo);
pthread_create(&updateSaveCommentsThread, 0, &PreviewModel::updateSaveCommentsTHelper, this);
} }
} }
@ -216,11 +186,13 @@ void PreviewModel::UpdateComments(int pageNumber)
notifyCommentsPageChanged(); notifyCommentsPageChanged();
//Threading //Threading
if(!updateSaveCommentsWorking) if (!updateSaveCommentsInfo)
updateSaveCommentsInfo = new threadInfo(tSaveID, commentsPageNumber);
if (updateSaveCommentsInfo->threadFinished)
{ {
updateSaveCommentsFinished = false; commentsLoaded = false;
updateSaveCommentsWorking = true; updateSaveCommentsInfo->threadFinished = false;
pthread_create(&updateSaveCommentsThread, 0, &PreviewModel::updateSaveCommentsTHelper, this); pthread_create(&updateSaveCommentsThread, 0, &PreviewModel::updateSaveCommentsT, updateSaveCommentsInfo);
} }
} }
@ -261,7 +233,8 @@ void PreviewModel::notifySaveCommentsChanged()
} }
} }
void PreviewModel::AddObserver(PreviewView * observer) { void PreviewModel::AddObserver(PreviewView * observer)
{
observers.push_back(observer); observers.push_back(observer);
observer->NotifySaveChanged(this); observer->NotifySaveChanged(this);
observer->NotifyCommentsChanged(this); observer->NotifyCommentsChanged(this);
@ -271,19 +244,20 @@ void PreviewModel::AddObserver(PreviewView * observer) {
void PreviewModel::Update() void PreviewModel::Update()
{ {
if(updateSaveDataWorking) if (updateSaveDataInfo)
{ {
if(updateSaveDataFinished) if (updateSaveDataInfo->threadFinished)
{ {
updateSaveDataWorking = false; delete updateSaveDataInfo;
pthread_join(updateSaveDataThread, NULL); updateSaveDataInfo = NULL;
pthread_join(updateSaveDataThread, (void**)(&saveData));
if(updateSaveInfoFinished && save) if (save)
{ {
commentsTotal = save->Comments; commentsTotal = save->Comments;
try try
{ {
save->SetGameSave(new GameSave(&saveDataBuffer[0], saveDataBuffer.size())); save->SetGameSave(new GameSave((char*)saveData->data, saveData->length));
} }
catch(ParseException &e) catch(ParseException &e)
{ {
@ -295,23 +269,24 @@ void PreviewModel::Update()
} }
} }
if(updateSaveInfoWorking) if (updateSaveInfoInfo)
{ {
if(updateSaveInfoFinished) if (updateSaveInfoInfo->threadFinished)
{ {
if (save) if (save)
{ {
delete save; delete save;
save = NULL; save = NULL;
} }
updateSaveInfoWorking = false; delete updateSaveInfoInfo;
updateSaveInfoInfo = NULL;
pthread_join(updateSaveInfoThread, (void**)(&save)); pthread_join(updateSaveInfoThread, (void**)(&save));
if(updateSaveDataFinished && save) if (save)
{ {
commentsTotal = save->Comments; commentsTotal = save->Comments;
try try
{ {
save->SetGameSave(new GameSave(&saveDataBuffer[0], saveDataBuffer.size())); save->SetGameSave(new GameSave((char*)saveData->data, saveData->length));
} }
catch(ParseException &e) catch(ParseException &e)
{ {
@ -326,9 +301,9 @@ void PreviewModel::Update()
} }
} }
if(updateSaveCommentsWorking) if (updateSaveCommentsInfo)
{ {
if(updateSaveCommentsFinished) if (updateSaveCommentsInfo->threadFinished)
{ {
if(saveComments) if(saveComments)
{ {
@ -339,29 +314,22 @@ void PreviewModel::Update()
saveComments = NULL; saveComments = NULL;
} }
commentsLoaded = true; commentsLoaded = true;
updateSaveCommentsWorking = false; delete updateSaveCommentsInfo;
updateSaveCommentsInfo = NULL;
pthread_join(updateSaveCommentsThread, (void**)(&saveComments)); pthread_join(updateSaveCommentsThread, (void**)(&saveComments));
notifySaveCommentsChanged(); notifySaveCommentsChanged();
} }
} }
} }
PreviewModel::~PreviewModel() { PreviewModel::~PreviewModel()
if (updateSaveDataWorking)
{ {
pthread_cancel(updateSaveDataThread); if (updateSaveDataInfo)
pthread_join(updateSaveDataThread, NULL); updateSaveDataInfo->previewExited = true;
} if (updateSaveInfoInfo)
if (updateSaveInfoWorking) updateSaveInfoInfo->previewExited = true;
{ if (updateSaveCommentsInfo)
pthread_cancel(updateSaveInfoThread); updateSaveCommentsInfo->previewExited = true;
pthread_join(updateSaveInfoThread, NULL);
}
if (updateSaveCommentsWorking)
{
pthread_cancel(updateSaveCommentsThread);
pthread_join(updateSaveCommentsThread, NULL);
}
if(save) if(save)
delete save; delete save;
if(saveComments) if(saveComments)
@ -371,6 +339,10 @@ PreviewModel::~PreviewModel() {
saveComments->clear(); saveComments->clear();
delete saveComments; delete saveComments;
} }
saveDataBuffer.clear(); if (saveData)
{
if (saveData->data)
free(saveData->data);
delete saveData;
}
} }

View File

@ -1,5 +1,5 @@
#ifndef PREVIEWMODEL_H_ #ifndef PREVIEWMODEL_H
#define PREVIEWMODEL_H_ #define PREVIEWMODEL_H
#include <vector> #include <vector>
#include <iostream> #include <iostream>
@ -14,17 +14,36 @@ using namespace std;
struct SaveData struct SaveData
{ {
SaveData(unsigned char * data_, int len):
data(data_),
length(len)
{
}
unsigned char * data; unsigned char * data;
int length; int length;
}; };
struct threadInfo {
threadInfo(int saveID_, int saveDate_):
threadFinished(true),
previewExited(false),
saveID(saveID_),
saveDate(saveDate_)
{
}
bool threadFinished;
bool previewExited;
int saveID;
int saveDate;
};
class PreviewView; class PreviewView;
class PreviewModel { class PreviewModel {
bool doOpen; bool doOpen;
bool commentBoxEnabled; bool commentBoxEnabled;
vector<PreviewView*> observers; vector<PreviewView*> observers;
SaveInfo * save; SaveInfo * save;
vector<char> saveDataBuffer; SaveData *saveData;
std::vector<SaveComment*> * saveComments; std::vector<SaveComment*> * saveComments;
void notifySaveChanged(); void notifySaveChanged();
void notifySaveCommentsChanged(); void notifySaveCommentsChanged();
@ -40,26 +59,17 @@ class PreviewModel {
int commentsTotal; int commentsTotal;
int commentsPageNumber; int commentsPageNumber;
bool updateSaveDataWorking; threadInfo * updateSaveDataInfo;
volatile bool updateSaveDataFinished;
pthread_t updateSaveDataThread; pthread_t updateSaveDataThread;
static void * updateSaveDataTHelper(void * obj); static void * updateSaveDataT(void * obj);
static void updateSaveDataTDelete(void * arg);
void * updateSaveDataT();
bool updateSaveInfoWorking; threadInfo * updateSaveInfoInfo;
volatile bool updateSaveInfoFinished;
pthread_t updateSaveInfoThread; pthread_t updateSaveInfoThread;
static void * updateSaveInfoTHelper(void * obj); static void * updateSaveInfoT(void * obj);
static void updateSaveInfoTDelete(void * arg);
void * updateSaveInfoT();
bool updateSaveCommentsWorking; threadInfo * updateSaveCommentsInfo;
volatile bool updateSaveCommentsFinished;
pthread_t updateSaveCommentsThread; pthread_t updateSaveCommentsThread;
static void * updateSaveCommentsTHelper(void * obj); static void * updateSaveCommentsT(void * obj);
static void updateSaveCommentsTDelete(void * arg);
void * updateSaveCommentsT();
public: public:
PreviewModel(); PreviewModel();
SaveInfo * GetSave(); SaveInfo * GetSave();
@ -82,4 +92,4 @@ public:
virtual ~PreviewModel(); virtual ~PreviewModel();
}; };
#endif /* PREVIEWMODEL_H_ */ #endif /* PREVIEWMODEL_H */