summaryrefslogtreecommitdiff
path: root/src/T2DLL/T2PluginLoader.cpp
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-06-14 00:50:34 +0100
committerAsh Wolf <ninji@wuffs.org>2023-06-14 00:50:34 +0100
commit37e364b2c6cc7487a1c888d256a73e5337bb7189 (patch)
treeeaf6e857382eef16c2dd940eb4125536fbe068bd /src/T2DLL/T2PluginLoader.cpp
downloadt2win-37e364b2c6cc7487a1c888d256a73e5337bb7189.tar.gz
t2win-37e364b2c6cc7487a1c888d256a73e5337bb7189.zip
initial commit
Diffstat (limited to '')
-rw-r--r--src/T2DLL/T2PluginLoader.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/T2DLL/T2PluginLoader.cpp b/src/T2DLL/T2PluginLoader.cpp
new file mode 100644
index 0000000..57867ed
--- /dev/null
+++ b/src/T2DLL/T2PluginLoader.cpp
@@ -0,0 +1,214 @@
+#include "CT2App.h"
+#include "GlobalFunc.h"
+#include "T2PluginLoader.h"
+#include "T2PluginSpecifier.h"
+
+T2PluginLoader::T2PluginLoader() {
+}
+
+T2PluginLoader::~T2PluginLoader() {
+ POSITION p = mList.GetHeadPosition();
+ while (p) {
+ T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p);
+ if (spec->mIsLoaded)
+ UnloadPlugin(spec);
+ delete spec;
+ }
+}
+
+void T2PluginLoader::InitFileList() {
+ char *dirBuf = (char *) malloc(1000);
+ GetTowerDirectory(dirBuf);
+ strcat(dirBuf, "Plugins\\");
+ char *dirBufEnd = &dirBuf[strlen(dirBuf)];
+
+ CString dbPath = GetTowerDirectory() + "plugins\\Database";
+ BOOL errorFlag = false;
+
+ CFile file;
+ if (file.Open(dbPath, CFile::modeRead)) {
+ CArchive archive(&file, CArchive::load);
+
+ DWORD count = mList.GetCount();
+ archive >> count;
+
+ for (unsigned int i = 0; i < count; i++) {
+ T2PluginSpecifier *spec = new T2PluginSpecifier;
+ spec->Read(archive);
+ mList.AddTail(spec);
+ }
+
+ archive.Close();
+ file.Close();
+
+ // check that the database is up-to-date
+ CFileStatus status;
+ int count2 = 0;
+
+ POSITION p = mList.GetHeadPosition();
+ while (p) {
+ T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p);
+ if (CFile::GetStatus(spec->mPath, status)) {
+ if (status.m_mtime == spec->mTime)
+ count2++;
+ }
+ }
+
+ if (count2 != mList.GetCount())
+ errorFlag = true;
+
+ count2 = 0;
+
+ strcpy(dirBufEnd, "*.t2p");
+ WIN32_FIND_DATA findData;
+ HANDLE findHandle = FindFirstFile(dirBuf, &findData);
+ BOOL findOK = (findHandle != INVALID_HANDLE_VALUE);
+ while (findOK) {
+ findOK = FindNextFile(findHandle, &findData);
+ count2++;
+ }
+ FindClose(findHandle);
+
+ if (count2 != mList.GetCount())
+ errorFlag = true;
+ } else {
+ errorFlag = true;
+ }
+
+ if (errorFlag) {
+ // update the DB
+ AfxSetResourceHandle(gT2App->m_hInstance);
+
+ CDialog *dialog = new CDialog;
+ dialog->Create(1000);
+ gT2App->app_vfB4();
+
+ POSITION p = mList.GetHeadPosition();
+ while (p) {
+ T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p);
+ delete spec;
+ }
+ mList.RemoveAll();
+
+ strcpy(dirBufEnd, "*.t2p");
+ WIN32_FIND_DATA findData;
+ HANDLE findHandle = FindFirstFile(dirBuf, &findData);
+ BOOL findOK = (findHandle != INVALID_HANDLE_VALUE);
+ while (findOK) {
+ strcpy(dirBufEnd, findData.cFileName);
+
+ T2PluginSpecifier *spec = new T2PluginSpecifier;
+ spec->Initialize(NULL, dirBuf);
+ spec->mInstance = NULL;
+ spec->mIsLoaded = false;
+ mList.AddTail(spec);
+
+ findOK = FindNextFile(findHandle, &findData);
+ }
+ FindClose(findHandle);
+
+ if (file.Open(dbPath, CFile::modeWrite | CFile::modeCreate)) {
+ CArchive archive(&file, CArchive::store);
+
+ DWORD count = mList.GetCount();
+ archive << count;
+
+ p = mList.GetHeadPosition();
+ while (p) {
+ T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p);
+ spec->Write(archive);
+ }
+
+ archive.Close();
+ file.Close();
+ }
+
+ dialog->DestroyWindow();
+ }
+
+ free(dirBuf);
+}
+
+typedef void *(MSVC_STDCALL* ConstructProgramPluginType) (T2PluginSpecifier *);
+typedef void (MSVC_STDCALL* DestructProgramPluginType) (void);
+
+/*static*/ void* T2PluginLoader::LoadPlugin(T2PluginSpecifier* spec) {
+ if (!spec->mIsLoaded) {
+ HMODULE module = LoadLibrary(spec->mPath);
+ spec->mInstance = (HINSTANCE) module;
+ }
+
+ ConstructProgramPluginType func = (ConstructProgramPluginType) GetProcAddress((HMODULE) spec->mInstance, "ConstructProgramPlugin");
+#line 142
+ _ASSERT(func);
+
+ spec->mIsLoaded = true;
+ return func(spec);
+}
+
+/*static*/ void T2PluginLoader::UnloadPlugin(T2PluginSpecifier* spec) {
+ if (spec->mIsSubPlugin) {
+ spec->mIsLoaded = false;
+ return;
+ }
+
+#line 154
+ _ASSERT(spec->mIsLoaded);
+ DestructProgramPluginType func = (DestructProgramPluginType) GetProcAddress((HMODULE) spec->mInstance, "DestructProgramPlugin");
+#line 156
+ _ASSERT(func);
+
+ spec->mIsLoaded = false;
+ func();
+ FreeLibrary((HMODULE) spec->mInstance);
+}
+
+void T2PluginLoader::SetTypeFilter(POSITION& p, DWORD type) {
+ p = mList.GetHeadPosition();
+
+ if (type)
+ mTypeFilter = type;
+ else
+ mTypeFilter = 0;
+}
+
+T2PluginSpecifier* T2PluginLoader::GetNext(POSITION& p) {
+ while (p) {
+ T2PluginSpecifier *spec = (T2PluginSpecifier *) mList.GetNext(p);
+ if (
+ (mTypeFilter == 0 || spec->mType == mTypeFilter) &&
+ (spec->m28 == -1 || spec->m28 == 1) // 1 might be a version constant here
+ )
+ return spec;
+ }
+
+ return NULL;
+}
+
+T2PluginSpecifier* T2PluginLoader::FindPlugin(DWORD id, DWORD type) {
+ POSITION p;
+ T2PluginSpecifier *spec;
+
+ SetTypeFilter(p, type);
+
+ while ((spec = GetNext(p))) {
+ if (spec->mID == id)
+ return spec;
+ }
+
+ return NULL;
+}
+
+T2PluginSpecifier* T2PluginLoader::FindPlugin(const char* name, DWORD type) {
+ POSITION p;
+ T2PluginSpecifier *spec;
+
+ SetTypeFilter(p, type);
+
+ while ((spec = GetNext(p))) {
+ if (spec->mPluginName == name)
+ return spec;
+ }
+
+ return NULL;
+}