mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 10:37:41 -04:00
Fix line endings and tabs
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -1,102 +1,102 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef SCENE_SYNC_H
|
||||
#define SCENE_SYNC_H
|
||||
|
||||
#include "Max.h"
|
||||
#include "notify.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class plMaxNode;
|
||||
class hsSemaphore;
|
||||
class SceneWatcher;
|
||||
class plSceneNode;
|
||||
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
class SceneSync
|
||||
{
|
||||
protected:
|
||||
SceneWatcher *fSceneWatcher;
|
||||
hsSemaphore *fUpdateSignal;
|
||||
const char *fPipeName;
|
||||
int fTimerID;
|
||||
int fUpdateFreq;
|
||||
|
||||
SceneSync();
|
||||
|
||||
public:
|
||||
static SceneSync& Instance();
|
||||
|
||||
// Get the path where the current Max file will be exported to (not including "dat")
|
||||
bool GetOutputDir(char *buf);
|
||||
|
||||
bool IsClientRunning();
|
||||
|
||||
// Is there valid data on disk that we can load into the ResMgr or do we need to reconvert?
|
||||
bool CanLoadOldResMgr();
|
||||
|
||||
// Create client data
|
||||
bool CreateClientData();
|
||||
|
||||
void SetUpdateFreq(int freq); // In milliseconds
|
||||
|
||||
// Start updating the client
|
||||
bool BeginClientSync(const char *semaphoreName, const char *pipeName);
|
||||
// Stop updating the client. If abort is true, don't try saving, something went wrong
|
||||
void EndClientSync(bool abort);
|
||||
|
||||
protected:
|
||||
bool SaveResMgr();
|
||||
|
||||
void IShutdownClient();
|
||||
|
||||
// Reconvert any dirty nodes to sync the Plasma database and the Max one
|
||||
bool Update();
|
||||
|
||||
void AddSceneNodes(std::set<plSceneNode*>& sceneNodes, std::vector<plUoid>& delUoids, std::vector<plKey>& newKeys);
|
||||
|
||||
bool IStartWatching(bool forceWatch=false);
|
||||
bool IStopWatching();
|
||||
|
||||
// Called by open and close scene.
|
||||
bool IReadNodeMap(const char *dir);
|
||||
bool IWriteNodeMap(const char *dir);
|
||||
|
||||
void IShutdown();
|
||||
|
||||
void IDeletePath(const char *path);
|
||||
void IClearDirtyRecur(plMaxNode *node);
|
||||
|
||||
static void INotify(void *param, NotifyInfo *info);
|
||||
|
||||
static void CALLBACK ITimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
||||
};
|
||||
|
||||
#endif //SCENE_SYNC_H
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef SCENE_SYNC_H
|
||||
#define SCENE_SYNC_H
|
||||
|
||||
#include "Max.h"
|
||||
#include "notify.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class plMaxNode;
|
||||
class hsSemaphore;
|
||||
class SceneWatcher;
|
||||
class plSceneNode;
|
||||
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
class SceneSync
|
||||
{
|
||||
protected:
|
||||
SceneWatcher *fSceneWatcher;
|
||||
hsSemaphore *fUpdateSignal;
|
||||
const char *fPipeName;
|
||||
int fTimerID;
|
||||
int fUpdateFreq;
|
||||
|
||||
SceneSync();
|
||||
|
||||
public:
|
||||
static SceneSync& Instance();
|
||||
|
||||
// Get the path where the current Max file will be exported to (not including "dat")
|
||||
bool GetOutputDir(char *buf);
|
||||
|
||||
bool IsClientRunning();
|
||||
|
||||
// Is there valid data on disk that we can load into the ResMgr or do we need to reconvert?
|
||||
bool CanLoadOldResMgr();
|
||||
|
||||
// Create client data
|
||||
bool CreateClientData();
|
||||
|
||||
void SetUpdateFreq(int freq); // In milliseconds
|
||||
|
||||
// Start updating the client
|
||||
bool BeginClientSync(const char *semaphoreName, const char *pipeName);
|
||||
// Stop updating the client. If abort is true, don't try saving, something went wrong
|
||||
void EndClientSync(bool abort);
|
||||
|
||||
protected:
|
||||
bool SaveResMgr();
|
||||
|
||||
void IShutdownClient();
|
||||
|
||||
// Reconvert any dirty nodes to sync the Plasma database and the Max one
|
||||
bool Update();
|
||||
|
||||
void AddSceneNodes(std::set<plSceneNode*>& sceneNodes, std::vector<plUoid>& delUoids, std::vector<plKey>& newKeys);
|
||||
|
||||
bool IStartWatching(bool forceWatch=false);
|
||||
bool IStopWatching();
|
||||
|
||||
// Called by open and close scene.
|
||||
bool IReadNodeMap(const char *dir);
|
||||
bool IWriteNodeMap(const char *dir);
|
||||
|
||||
void IShutdown();
|
||||
|
||||
void IDeletePath(const char *path);
|
||||
void IClearDirtyRecur(plMaxNode *node);
|
||||
|
||||
static void INotify(void *param, NotifyInfo *info);
|
||||
|
||||
static void CALLBACK ITimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
||||
};
|
||||
|
||||
#endif //SCENE_SYNC_H
|
||||
|
@ -1,280 +1,280 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "SceneViewer.h"
|
||||
#include "SceneSync.h"
|
||||
|
||||
#include "../MaxMain/plMaxCFGFile.h"
|
||||
|
||||
#include "../MaxMain/resource.h"
|
||||
|
||||
// For ShellExecute
|
||||
#include <shellapi.h>
|
||||
|
||||
static const char *kDebugClientExe = "plClient_dbg.exe";
|
||||
static const char *kReleaseClientExe = "plClient.exe";
|
||||
|
||||
static const char *kSemaphoreName = "PlasmaSceneViewer";
|
||||
static const char *kPipeName = "\\\\.\\pipe\\PlasmaSceneViewer";
|
||||
|
||||
SceneViewer::SceneViewer() : fhDlg(NULL)
|
||||
{
|
||||
// Get the plugin CFG dir
|
||||
const char *plugFile = plMaxConfig::GetPluginIni();
|
||||
|
||||
fUpdate = (GetPrivateProfileInt("SceneViewer", "Update", 1, plugFile) != 0);
|
||||
fUpdateFreq = GetPrivateProfileInt("SceneViewer", "UpdateFreq", 500, plugFile);
|
||||
fLoadOld = (GetPrivateProfileInt("SceneViewer", "LoadOld", 0, plugFile) != 0);
|
||||
fReleaseExe = (GetPrivateProfileInt("SceneViewer", "ReleaseExe", 1, plugFile) != 0);
|
||||
}
|
||||
|
||||
SceneViewer::~SceneViewer()
|
||||
{
|
||||
// Make sure the client is shut down
|
||||
ISetRunning(false);
|
||||
|
||||
// Get the plugin CFG dir
|
||||
const char *plugFile = plMaxConfig::GetPluginIni();
|
||||
|
||||
char buf[20];
|
||||
WritePrivateProfileString("SceneViewer", "Update", fUpdate ? "1" : "0", plugFile);
|
||||
WritePrivateProfileString("SceneViewer", "UpdateFreq", itoa(fUpdateFreq, buf, 10), plugFile);
|
||||
WritePrivateProfileString("SceneViewer", "LoadOld", fLoadOld ? "1" : "0", plugFile);
|
||||
WritePrivateProfileString("SceneViewer", "ReleaseExe", fReleaseExe ? "1" : "0", plugFile);
|
||||
}
|
||||
|
||||
SceneViewer &SceneViewer::Instance()
|
||||
{
|
||||
static SceneViewer theInstance;
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
void SceneViewer::Show()
|
||||
{
|
||||
// If the dialog is already created, make sure it is visible
|
||||
if (fhDlg)
|
||||
{
|
||||
if (IsIconic(fhDlg))
|
||||
ShowWindow(fhDlg, SW_RESTORE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fhDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_SCENEVIEWER), GetCOREInterface()->GetMAXHWnd(), ForwardDlgProc);
|
||||
}
|
||||
}
|
||||
|
||||
// Toggles the client and SceneSync
|
||||
bool SceneViewer::IToggleRunning()
|
||||
{
|
||||
fRunning = !fRunning;
|
||||
return ISetRunning(fRunning);
|
||||
}
|
||||
|
||||
// Starts/Stops the client and SceneSync
|
||||
bool SceneViewer::ISetRunning(bool running)
|
||||
{
|
||||
if (running)
|
||||
{
|
||||
// The client actually is running, hmmm
|
||||
if (SceneSync::Instance().IsClientRunning())
|
||||
return true;
|
||||
|
||||
// If we're not loading old data, or we are but it's not there, try to create some.
|
||||
if (!fLoadOld || !SceneSync::Instance().CanLoadOldResMgr())
|
||||
{
|
||||
// If creation fails, fail
|
||||
if (!SceneSync::Instance().CreateClientData())
|
||||
return false;
|
||||
}
|
||||
|
||||
char path[MAX_PATH];
|
||||
SceneSync::Instance().GetOutputDir(path);
|
||||
strcat(path, "dat\\");
|
||||
|
||||
// Start the client
|
||||
char *options = TRACKED_NEW char[strlen(path)+2+strlen(kSemaphoreName)+strlen(kPipeName)+6];
|
||||
sprintf(options, "-s %s %s \"%s\"", kSemaphoreName, kPipeName, path);
|
||||
|
||||
int ret = (int)ShellExecute(NULL,
|
||||
"open",
|
||||
fReleaseExe ? kReleaseClientExe : kDebugClientExe,
|
||||
options,
|
||||
plMaxConfig::GetClientPath(),
|
||||
SW_SHOWNORMAL);
|
||||
delete [] options;
|
||||
|
||||
// Client start failed
|
||||
if (ret < 32)
|
||||
return false;
|
||||
|
||||
// Start client sync
|
||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
||||
SceneSync::Instance().BeginClientSync(kSemaphoreName, kPipeName);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SceneSync::Instance().IsClientRunning())
|
||||
SceneSync::Instance().EndClientSync(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL SceneViewer::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return Instance().DlgProc(hDlg, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL SceneViewer::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
fhDlg = hDlg;
|
||||
|
||||
// Set the exe to use
|
||||
HWND hExeCombo = GetDlgItem(hDlg, IDC_EXE);
|
||||
ComboBox_AddString(hExeCombo, "Release");
|
||||
ComboBox_AddString(hExeCombo, "Debug");
|
||||
ComboBox_SetCurSel(hExeCombo, fReleaseExe ? 0 : 1);
|
||||
|
||||
// Set the client path
|
||||
const char *path = plMaxConfig::GetClientPath(false, true);
|
||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH));
|
||||
edit->SetText((char*)path);
|
||||
|
||||
// Set the "Load old data" checkbox
|
||||
HWND hLoadOld = GetDlgItem(hDlg, IDC_REUSE_DATA);
|
||||
Button_SetCheck(hLoadOld, fLoadOld ? BST_CHECKED : BST_UNCHECKED);
|
||||
Button_Enable(hLoadOld, SceneSync::Instance().CanLoadOldResMgr());
|
||||
|
||||
// Set the update controls
|
||||
float val = float(fUpdateFreq) / 1000.f;
|
||||
ISpinnerControl *spin = SetupFloatSpinner(hDlg, IDC_SPINNER, IDC_EDIT, 0.1, 1.f, val);
|
||||
spin->Enable(fUpdate);
|
||||
CheckDlgButton(hDlg, IDC_UPDATE, fUpdate ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning());
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
// Start/Stop SceneViewer
|
||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_START)
|
||||
{
|
||||
IToggleRunning();
|
||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning());
|
||||
return TRUE;
|
||||
}
|
||||
// Close dialog
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
|
||||
{
|
||||
DestroyWindow(hDlg);
|
||||
fhDlg = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
// Browse for directory
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_DIR)
|
||||
{
|
||||
const char *path = plMaxConfig::GetClientPath(true);
|
||||
if (path)
|
||||
{
|
||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH));
|
||||
edit->SetText((char*)path);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
// "Load old data" selection changed
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_REUSE_DATA)
|
||||
{
|
||||
fLoadOld = (Button_GetCheck((HWND)lParam) == BST_CHECKED);
|
||||
return TRUE;
|
||||
}
|
||||
// Release/Debug exe selection changed
|
||||
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_EXE)
|
||||
{
|
||||
int sel = ComboBox_GetCurSel((HWND)lParam);
|
||||
fReleaseExe = (sel == 0);
|
||||
return TRUE;
|
||||
}
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_UPDATE)
|
||||
{
|
||||
fUpdate = (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
||||
|
||||
ISpinnerControl *spin = GetISpinner(GetDlgItem(hDlg, IDC_SPINNER));
|
||||
spin->Enable(fUpdate);
|
||||
ReleaseISpinner(spin);
|
||||
|
||||
// If update was turned on, send out an update message so any dirty objects
|
||||
// will be reconverted right away
|
||||
if (fUpdate)
|
||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
// Update frequency changed
|
||||
case CC_SPINNER_CHANGE:
|
||||
if (LOWORD(wParam) == IDC_SPINNER)
|
||||
{
|
||||
ISpinnerControl *spin = (ISpinnerControl*)lParam;
|
||||
float val = spin->GetFVal();
|
||||
fUpdateFreq = int(val*1000.f);
|
||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
// Type in directory
|
||||
case WM_CUSTEDIT_ENTER:
|
||||
if (wParam == IDC_CLIENT_PATH)
|
||||
{
|
||||
ICustEdit *edit = GetICustEdit((HWND)lParam);
|
||||
|
||||
char path[MAX_PATH];
|
||||
edit->GetText(path, sizeof(path));
|
||||
plMaxConfig::SetClientPath(path);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SceneViewer::IEnableSetupControls(bool enable)
|
||||
{
|
||||
ICustEdit *edit = GetICustEdit(GetDlgItem(fhDlg, IDC_CLIENT_PATH));
|
||||
edit->Enable(enable);
|
||||
|
||||
EnableWindow(GetDlgItem(fhDlg, IDC_DIR), enable);
|
||||
EnableWindow(GetDlgItem(fhDlg, IDC_EXE), enable);
|
||||
EnableWindow(GetDlgItem(fhDlg, IDC_REUSE_DATA), enable);
|
||||
|
||||
SetWindowText(GetDlgItem(fhDlg, IDC_START), enable ? "Start" : "Stop");
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "SceneViewer.h"
|
||||
#include "SceneSync.h"
|
||||
|
||||
#include "../MaxMain/plMaxCFGFile.h"
|
||||
|
||||
#include "../MaxMain/resource.h"
|
||||
|
||||
// For ShellExecute
|
||||
#include <shellapi.h>
|
||||
|
||||
static const char *kDebugClientExe = "plClient_dbg.exe";
|
||||
static const char *kReleaseClientExe = "plClient.exe";
|
||||
|
||||
static const char *kSemaphoreName = "PlasmaSceneViewer";
|
||||
static const char *kPipeName = "\\\\.\\pipe\\PlasmaSceneViewer";
|
||||
|
||||
SceneViewer::SceneViewer() : fhDlg(NULL)
|
||||
{
|
||||
// Get the plugin CFG dir
|
||||
const char *plugFile = plMaxConfig::GetPluginIni();
|
||||
|
||||
fUpdate = (GetPrivateProfileInt("SceneViewer", "Update", 1, plugFile) != 0);
|
||||
fUpdateFreq = GetPrivateProfileInt("SceneViewer", "UpdateFreq", 500, plugFile);
|
||||
fLoadOld = (GetPrivateProfileInt("SceneViewer", "LoadOld", 0, plugFile) != 0);
|
||||
fReleaseExe = (GetPrivateProfileInt("SceneViewer", "ReleaseExe", 1, plugFile) != 0);
|
||||
}
|
||||
|
||||
SceneViewer::~SceneViewer()
|
||||
{
|
||||
// Make sure the client is shut down
|
||||
ISetRunning(false);
|
||||
|
||||
// Get the plugin CFG dir
|
||||
const char *plugFile = plMaxConfig::GetPluginIni();
|
||||
|
||||
char buf[20];
|
||||
WritePrivateProfileString("SceneViewer", "Update", fUpdate ? "1" : "0", plugFile);
|
||||
WritePrivateProfileString("SceneViewer", "UpdateFreq", itoa(fUpdateFreq, buf, 10), plugFile);
|
||||
WritePrivateProfileString("SceneViewer", "LoadOld", fLoadOld ? "1" : "0", plugFile);
|
||||
WritePrivateProfileString("SceneViewer", "ReleaseExe", fReleaseExe ? "1" : "0", plugFile);
|
||||
}
|
||||
|
||||
SceneViewer &SceneViewer::Instance()
|
||||
{
|
||||
static SceneViewer theInstance;
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
void SceneViewer::Show()
|
||||
{
|
||||
// If the dialog is already created, make sure it is visible
|
||||
if (fhDlg)
|
||||
{
|
||||
if (IsIconic(fhDlg))
|
||||
ShowWindow(fhDlg, SW_RESTORE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fhDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_SCENEVIEWER), GetCOREInterface()->GetMAXHWnd(), ForwardDlgProc);
|
||||
}
|
||||
}
|
||||
|
||||
// Toggles the client and SceneSync
|
||||
bool SceneViewer::IToggleRunning()
|
||||
{
|
||||
fRunning = !fRunning;
|
||||
return ISetRunning(fRunning);
|
||||
}
|
||||
|
||||
// Starts/Stops the client and SceneSync
|
||||
bool SceneViewer::ISetRunning(bool running)
|
||||
{
|
||||
if (running)
|
||||
{
|
||||
// The client actually is running, hmmm
|
||||
if (SceneSync::Instance().IsClientRunning())
|
||||
return true;
|
||||
|
||||
// If we're not loading old data, or we are but it's not there, try to create some.
|
||||
if (!fLoadOld || !SceneSync::Instance().CanLoadOldResMgr())
|
||||
{
|
||||
// If creation fails, fail
|
||||
if (!SceneSync::Instance().CreateClientData())
|
||||
return false;
|
||||
}
|
||||
|
||||
char path[MAX_PATH];
|
||||
SceneSync::Instance().GetOutputDir(path);
|
||||
strcat(path, "dat\\");
|
||||
|
||||
// Start the client
|
||||
char *options = TRACKED_NEW char[strlen(path)+2+strlen(kSemaphoreName)+strlen(kPipeName)+6];
|
||||
sprintf(options, "-s %s %s \"%s\"", kSemaphoreName, kPipeName, path);
|
||||
|
||||
int ret = (int)ShellExecute(NULL,
|
||||
"open",
|
||||
fReleaseExe ? kReleaseClientExe : kDebugClientExe,
|
||||
options,
|
||||
plMaxConfig::GetClientPath(),
|
||||
SW_SHOWNORMAL);
|
||||
delete [] options;
|
||||
|
||||
// Client start failed
|
||||
if (ret < 32)
|
||||
return false;
|
||||
|
||||
// Start client sync
|
||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
||||
SceneSync::Instance().BeginClientSync(kSemaphoreName, kPipeName);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SceneSync::Instance().IsClientRunning())
|
||||
SceneSync::Instance().EndClientSync(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL SceneViewer::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return Instance().DlgProc(hDlg, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL SceneViewer::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
fhDlg = hDlg;
|
||||
|
||||
// Set the exe to use
|
||||
HWND hExeCombo = GetDlgItem(hDlg, IDC_EXE);
|
||||
ComboBox_AddString(hExeCombo, "Release");
|
||||
ComboBox_AddString(hExeCombo, "Debug");
|
||||
ComboBox_SetCurSel(hExeCombo, fReleaseExe ? 0 : 1);
|
||||
|
||||
// Set the client path
|
||||
const char *path = plMaxConfig::GetClientPath(false, true);
|
||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH));
|
||||
edit->SetText((char*)path);
|
||||
|
||||
// Set the "Load old data" checkbox
|
||||
HWND hLoadOld = GetDlgItem(hDlg, IDC_REUSE_DATA);
|
||||
Button_SetCheck(hLoadOld, fLoadOld ? BST_CHECKED : BST_UNCHECKED);
|
||||
Button_Enable(hLoadOld, SceneSync::Instance().CanLoadOldResMgr());
|
||||
|
||||
// Set the update controls
|
||||
float val = float(fUpdateFreq) / 1000.f;
|
||||
ISpinnerControl *spin = SetupFloatSpinner(hDlg, IDC_SPINNER, IDC_EDIT, 0.1, 1.f, val);
|
||||
spin->Enable(fUpdate);
|
||||
CheckDlgButton(hDlg, IDC_UPDATE, fUpdate ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning());
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
// Start/Stop SceneViewer
|
||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_START)
|
||||
{
|
||||
IToggleRunning();
|
||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning());
|
||||
return TRUE;
|
||||
}
|
||||
// Close dialog
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
|
||||
{
|
||||
DestroyWindow(hDlg);
|
||||
fhDlg = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
// Browse for directory
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_DIR)
|
||||
{
|
||||
const char *path = plMaxConfig::GetClientPath(true);
|
||||
if (path)
|
||||
{
|
||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH));
|
||||
edit->SetText((char*)path);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
// "Load old data" selection changed
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_REUSE_DATA)
|
||||
{
|
||||
fLoadOld = (Button_GetCheck((HWND)lParam) == BST_CHECKED);
|
||||
return TRUE;
|
||||
}
|
||||
// Release/Debug exe selection changed
|
||||
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_EXE)
|
||||
{
|
||||
int sel = ComboBox_GetCurSel((HWND)lParam);
|
||||
fReleaseExe = (sel == 0);
|
||||
return TRUE;
|
||||
}
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_UPDATE)
|
||||
{
|
||||
fUpdate = (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
||||
|
||||
ISpinnerControl *spin = GetISpinner(GetDlgItem(hDlg, IDC_SPINNER));
|
||||
spin->Enable(fUpdate);
|
||||
ReleaseISpinner(spin);
|
||||
|
||||
// If update was turned on, send out an update message so any dirty objects
|
||||
// will be reconverted right away
|
||||
if (fUpdate)
|
||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
// Update frequency changed
|
||||
case CC_SPINNER_CHANGE:
|
||||
if (LOWORD(wParam) == IDC_SPINNER)
|
||||
{
|
||||
ISpinnerControl *spin = (ISpinnerControl*)lParam;
|
||||
float val = spin->GetFVal();
|
||||
fUpdateFreq = int(val*1000.f);
|
||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
// Type in directory
|
||||
case WM_CUSTEDIT_ENTER:
|
||||
if (wParam == IDC_CLIENT_PATH)
|
||||
{
|
||||
ICustEdit *edit = GetICustEdit((HWND)lParam);
|
||||
|
||||
char path[MAX_PATH];
|
||||
edit->GetText(path, sizeof(path));
|
||||
plMaxConfig::SetClientPath(path);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SceneViewer::IEnableSetupControls(bool enable)
|
||||
{
|
||||
ICustEdit *edit = GetICustEdit(GetDlgItem(fhDlg, IDC_CLIENT_PATH));
|
||||
edit->Enable(enable);
|
||||
|
||||
EnableWindow(GetDlgItem(fhDlg, IDC_DIR), enable);
|
||||
EnableWindow(GetDlgItem(fhDlg, IDC_EXE), enable);
|
||||
EnableWindow(GetDlgItem(fhDlg, IDC_REUSE_DATA), enable);
|
||||
|
||||
SetWindowText(GetDlgItem(fhDlg, IDC_START), enable ? "Start" : "Stop");
|
||||
}
|
||||
|
@ -1,61 +1,61 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef SceneViewer_h_inc
|
||||
#define SceneViewer_h_inc
|
||||
|
||||
#include "hsWindows.h"
|
||||
|
||||
// The dialog for setting up and starting the SceneViewer. Controls starting the client
|
||||
// and SceneSync; SceneSync controls the updates though.
|
||||
class SceneViewer
|
||||
{
|
||||
protected:
|
||||
bool fUpdate;
|
||||
int fUpdateFreq; // Update rate (ms), -1 for no update
|
||||
bool fLoadOld; // Load old data if possible
|
||||
bool fReleaseExe; // True for release exe, false for debug
|
||||
bool fRunning; // Do we think the client is currently running (not sure since the
|
||||
// client can terminate without us knowing).
|
||||
HWND fhDlg; // Handle to the setup dialog
|
||||
|
||||
SceneViewer();
|
||||
|
||||
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void IEnableSetupControls(bool enable);
|
||||
|
||||
bool IToggleRunning();
|
||||
bool ISetRunning(bool running);
|
||||
|
||||
public:
|
||||
~SceneViewer();
|
||||
static SceneViewer &Instance();
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef SceneViewer_h_inc
|
||||
#define SceneViewer_h_inc
|
||||
|
||||
#include "hsWindows.h"
|
||||
|
||||
// The dialog for setting up and starting the SceneViewer. Controls starting the client
|
||||
// and SceneSync; SceneSync controls the updates though.
|
||||
class SceneViewer
|
||||
{
|
||||
protected:
|
||||
bool fUpdate;
|
||||
int fUpdateFreq; // Update rate (ms), -1 for no update
|
||||
bool fLoadOld; // Load old data if possible
|
||||
bool fReleaseExe; // True for release exe, false for debug
|
||||
bool fRunning; // Do we think the client is currently running (not sure since the
|
||||
// client can terminate without us knowing).
|
||||
HWND fhDlg; // Handle to the setup dialog
|
||||
|
||||
SceneViewer();
|
||||
|
||||
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void IEnableSetupControls(bool enable);
|
||||
|
||||
bool IToggleRunning();
|
||||
bool ISetRunning(bool running);
|
||||
|
||||
public:
|
||||
~SceneViewer();
|
||||
static SceneViewer &Instance();
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
#endif // SceneViewer_h_inc
|
@ -1,352 +1,352 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
|
||||
#include "SceneWatcher.h"
|
||||
|
||||
#include "../MaxMain/plMaxNode.h"
|
||||
#include "../MaxComponent/plComponent.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
SceneWatcher::SceneWatcher() : fDirty(false)
|
||||
{
|
||||
RegisterNotification(INotify, this, NOTIFY_NODE_CREATED);
|
||||
IAddNodeRecur((plMaxNode*)GetCOREInterface()->GetRootNode());
|
||||
}
|
||||
|
||||
SceneWatcher::~SceneWatcher()
|
||||
{
|
||||
DeleteAllRefsFromMe();
|
||||
UnRegisterNotification(INotify, this, NOTIFY_NODE_CREATED);
|
||||
}
|
||||
|
||||
int SceneWatcher::NumRefs()
|
||||
{
|
||||
return fNodes.size();
|
||||
}
|
||||
|
||||
RefTargetHandle SceneWatcher::GetReference(int i)
|
||||
{
|
||||
if (i < fNodes.size())
|
||||
return fNodes[i];
|
||||
|
||||
hsAssert(0, "Index out of range");
|
||||
return nil;
|
||||
}
|
||||
|
||||
void SceneWatcher::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
if (i < fNodes.size())
|
||||
fNodes[i] = (plMaxNode*)rtarg;
|
||||
else
|
||||
hsAssert(0, "Index out of range");
|
||||
}
|
||||
|
||||
//
|
||||
// Something in the scene has changed.
|
||||
//
|
||||
RefResult SceneWatcher::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
plMaxNode *node = (plMaxNode *)hTarget;
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
char *tmp = node->GetName();
|
||||
#endif
|
||||
|
||||
if (message == REFMSG_CHANGE)
|
||||
{
|
||||
// If the message is from a component, and was not generated locally (ie.
|
||||
// it came from a ref parameter), ignore it. There is no way to tell if
|
||||
// one of these messages is an actual change to the component or just a
|
||||
// change to the referenced object. We'll catch the real changes with
|
||||
// REFMSG_USER_COMP_REF_CHANGED below.
|
||||
if (node->IsComponent())
|
||||
{
|
||||
plComponentBase *comp = node->ConvertToComponent();
|
||||
if (!comp->IsCurMsgLocal())
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
// If this is a static light, ignore it
|
||||
Object *obj = node->GetObjectRef();
|
||||
if (obj && obj->SuperClassID() == LIGHT_CLASS_ID && !node->GetRunTimeLight())
|
||||
return REF_SUCCEED;
|
||||
|
||||
node->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
else if (message == REFMSG_TARGET_DELETED)
|
||||
{
|
||||
// If the deleted node was a component, dirty everyone it was attached to
|
||||
if (node->IsComponent())
|
||||
{
|
||||
plComponentBase *comp = node->ConvertToComponent();
|
||||
for (UInt32 i = 0; i < comp->NumTargets(); i++)
|
||||
{
|
||||
if (comp->GetTarget(i))
|
||||
comp->GetTarget(i)->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
}
|
||||
}
|
||||
|
||||
fDeleted.push_back(node->GetKey());
|
||||
|
||||
IRemoveRef(node);
|
||||
ISetDirty();
|
||||
}
|
||||
else if (message == REFMSG_NODE_MATERIAL_CHANGED ||
|
||||
message == REFMSG_USER_MAT)
|
||||
{
|
||||
if (!node->IsComponent())
|
||||
{
|
||||
node->SetDirty(plMaxNode::kMatDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
}
|
||||
// A node was added to the components target list
|
||||
else if (message == REFMSG_USER_TARGET_ADD)
|
||||
{
|
||||
plMaxNode *target = (plMaxNode*)partID;
|
||||
target->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
// A node was deleted from the components target list
|
||||
else if (message == REFMSG_USER_TARGET_DELETE)
|
||||
{
|
||||
plMaxNode *target = (plMaxNode*)partID;
|
||||
target->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
// A ref maintained by a component PB changed (not just a propagated message
|
||||
// from the ref)
|
||||
else if (message == REFMSG_USER_COMP_REF_CHANGED)
|
||||
{
|
||||
node->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
bool SceneWatcher::AnyDeleted()
|
||||
{
|
||||
return !fDeleted.empty();
|
||||
}
|
||||
|
||||
SceneWatcher::KeyList& SceneWatcher::GetDeleted()
|
||||
{
|
||||
return fDeleted;
|
||||
}
|
||||
|
||||
const SceneWatcher::NodeList& SceneWatcher::GetWatchNodes()
|
||||
{
|
||||
return fNodes;
|
||||
}
|
||||
|
||||
bool SceneWatcher::AnyDirty()
|
||||
{
|
||||
return fDirty;
|
||||
}
|
||||
|
||||
void SceneWatcher::GetDirty(NodeSet& dirtyNodes)
|
||||
{
|
||||
int size = fNodes.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
plMaxNode *node = fNodes[i];
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
const char *tmp = node ? node->GetName() : nil;
|
||||
#endif
|
||||
// If any dirty flags are set, add to dirty list
|
||||
if (node && node->GetDirty(plMaxNode::kAllDirty))
|
||||
IGetDependents(node, dirtyNodes);
|
||||
}
|
||||
|
||||
fDirty = false;
|
||||
}
|
||||
|
||||
void SceneWatcher::IAddRef(plMaxNode *node)
|
||||
{
|
||||
// Ensure that we don't already ref this node
|
||||
if (FindRef(node) != -1)
|
||||
return;
|
||||
|
||||
// Make a ref
|
||||
int size = fNodes.size();
|
||||
fNodes.resize(size+1);
|
||||
MakeRefByID(FOREVER, size, node);
|
||||
}
|
||||
|
||||
void SceneWatcher::IRemoveRef(plMaxNode *node)
|
||||
{
|
||||
// Delete the reference if it's in our list
|
||||
int i = FindRef(node);
|
||||
|
||||
if (i != -1)
|
||||
{
|
||||
// Clear the node data, in case it is undeleted later
|
||||
// (when it will be invalid)
|
||||
node->ClearData(nil, nil);
|
||||
node->SetDirty(plMaxNode::kAllDirty, true);
|
||||
|
||||
// We can never really delete this reference because the user may "undo"
|
||||
// and cause it to come back, which just sets the reference again.
|
||||
fNodes[i] = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::IAddNodeRecur(plMaxNode *node)
|
||||
{
|
||||
IAddRef(node);
|
||||
|
||||
// If a node is dirty, make sure to set the dirty flag (since nodes may have
|
||||
// been dirtied in a previous run but not reconverted yet).
|
||||
if (node->GetDirty(plMaxNode::kAllDirty))
|
||||
fDirty = true;
|
||||
|
||||
for (int i = 0; i < node->NumberOfChildren(); ++i)
|
||||
{
|
||||
plMaxNode *childNode = (plMaxNode*)node->GetChildNode(i);
|
||||
IAddNodeRecur(childNode);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::INotify(void *param, NotifyInfo *info)
|
||||
{
|
||||
SceneWatcher *inst = (SceneWatcher*)param;
|
||||
|
||||
int code = info->intcode;
|
||||
|
||||
// New node was added to the scene, add it to our refs
|
||||
if (code == NOTIFY_NODE_CREATED)
|
||||
{
|
||||
plMaxNode *node = (plMaxNode*)info->callParam;
|
||||
|
||||
// Add a ref to the node and set it to dirty
|
||||
inst->IAddRef(node);
|
||||
node->SetDirty(plMaxNodeBase::kAllDirty, true);
|
||||
inst->ISetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::ISetDirty()
|
||||
{
|
||||
fDirty = true;
|
||||
}
|
||||
|
||||
#include "../MaxComponent/plMiscComponents.h"
|
||||
|
||||
#include "../MaxExport/plExportErrorMsg.h"
|
||||
#include "../MaxExport/plExportProgressBar.h"
|
||||
#include "../MaxComponent/plResponderComponent.h" // Just need the CID
|
||||
|
||||
void SceneWatcher::IGetLogicDependents(plMaxNode *node, NodeSet& nodes)
|
||||
{
|
||||
int attached = node->NumAttachedComponents();
|
||||
for (int i = 0; i < attached; i++)
|
||||
{
|
||||
plComponentBase *comp = node->GetAttachedComponent(i);
|
||||
/*
|
||||
if (comp->ClassID() == ACTIVATOR_CID)
|
||||
{
|
||||
plMaxNodeBase *activatorNode = comp->GetINode();
|
||||
int numResponders = activatorNode->NumAttachedComponents(true);
|
||||
for (int i = 0; i < numResponders; i++)
|
||||
{
|
||||
plComponentBase *responderComp = activatorNode->GetAttachedComponent(i, true);
|
||||
if (responderComp->ClassID() == RESPONDER_CID)
|
||||
{
|
||||
for (int j = 0; j < responderComp->NumTargets(); j++)
|
||||
{
|
||||
plMaxNode *targ = (plMaxNode*)responderComp->GetTarget(j);
|
||||
if (targ && nodes.find(targ) == nodes.end())
|
||||
{
|
||||
nodes.insert(targ);
|
||||
IGetLogicDependents(targ, nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (comp->ClassID() == RESPONDER_CID)
|
||||
{
|
||||
int activatorCnt = ResponderGetActivatorCount(comp);
|
||||
for (int i = 0; i < activatorCnt; i++)
|
||||
{
|
||||
plComponentBase *activator = ResponderGetActivator(comp, i);
|
||||
|
||||
for (int j = 0; j < activator->NumTargets(); j++)
|
||||
{
|
||||
plMaxNode *targ = (plMaxNode*)activator->GetTarget(j);
|
||||
if (targ && nodes.find(targ) == nodes.end())
|
||||
{
|
||||
nodes.insert(targ);
|
||||
IGetLogicDependents(targ, nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::IGetDependents(plMaxNode *node, NodeSet& nodes)
|
||||
{
|
||||
NodeSet dependents;
|
||||
|
||||
if (node->IsComponent())
|
||||
{
|
||||
plComponentBase *comp = node->ConvertToComponent();
|
||||
|
||||
if (comp->ClassID() == ROOM_CID || comp->ClassID() == PAGEINFO_CID)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < comp->NumTargets(); i++)
|
||||
{
|
||||
plMaxNode *targ = (plMaxNode*)comp->GetTarget(i);
|
||||
if (targ)
|
||||
{
|
||||
dependents.insert(targ);
|
||||
IGetLogicDependents(targ, dependents);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dependents.insert(node);
|
||||
|
||||
IGetLogicDependents(node, dependents);
|
||||
}
|
||||
|
||||
// Bug in VC++?
|
||||
// nodes.insert(dependents.begin(), dependents.end());
|
||||
for (NodeSet::iterator i = dependents.begin(); i != dependents.end(); i++)
|
||||
nodes.insert(*i);
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
|
||||
#include "SceneWatcher.h"
|
||||
|
||||
#include "../MaxMain/plMaxNode.h"
|
||||
#include "../MaxComponent/plComponent.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
SceneWatcher::SceneWatcher() : fDirty(false)
|
||||
{
|
||||
RegisterNotification(INotify, this, NOTIFY_NODE_CREATED);
|
||||
IAddNodeRecur((plMaxNode*)GetCOREInterface()->GetRootNode());
|
||||
}
|
||||
|
||||
SceneWatcher::~SceneWatcher()
|
||||
{
|
||||
DeleteAllRefsFromMe();
|
||||
UnRegisterNotification(INotify, this, NOTIFY_NODE_CREATED);
|
||||
}
|
||||
|
||||
int SceneWatcher::NumRefs()
|
||||
{
|
||||
return fNodes.size();
|
||||
}
|
||||
|
||||
RefTargetHandle SceneWatcher::GetReference(int i)
|
||||
{
|
||||
if (i < fNodes.size())
|
||||
return fNodes[i];
|
||||
|
||||
hsAssert(0, "Index out of range");
|
||||
return nil;
|
||||
}
|
||||
|
||||
void SceneWatcher::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
if (i < fNodes.size())
|
||||
fNodes[i] = (plMaxNode*)rtarg;
|
||||
else
|
||||
hsAssert(0, "Index out of range");
|
||||
}
|
||||
|
||||
//
|
||||
// Something in the scene has changed.
|
||||
//
|
||||
RefResult SceneWatcher::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
plMaxNode *node = (plMaxNode *)hTarget;
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
char *tmp = node->GetName();
|
||||
#endif
|
||||
|
||||
if (message == REFMSG_CHANGE)
|
||||
{
|
||||
// If the message is from a component, and was not generated locally (ie.
|
||||
// it came from a ref parameter), ignore it. There is no way to tell if
|
||||
// one of these messages is an actual change to the component or just a
|
||||
// change to the referenced object. We'll catch the real changes with
|
||||
// REFMSG_USER_COMP_REF_CHANGED below.
|
||||
if (node->IsComponent())
|
||||
{
|
||||
plComponentBase *comp = node->ConvertToComponent();
|
||||
if (!comp->IsCurMsgLocal())
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
// If this is a static light, ignore it
|
||||
Object *obj = node->GetObjectRef();
|
||||
if (obj && obj->SuperClassID() == LIGHT_CLASS_ID && !node->GetRunTimeLight())
|
||||
return REF_SUCCEED;
|
||||
|
||||
node->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
else if (message == REFMSG_TARGET_DELETED)
|
||||
{
|
||||
// If the deleted node was a component, dirty everyone it was attached to
|
||||
if (node->IsComponent())
|
||||
{
|
||||
plComponentBase *comp = node->ConvertToComponent();
|
||||
for (UInt32 i = 0; i < comp->NumTargets(); i++)
|
||||
{
|
||||
if (comp->GetTarget(i))
|
||||
comp->GetTarget(i)->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
}
|
||||
}
|
||||
|
||||
fDeleted.push_back(node->GetKey());
|
||||
|
||||
IRemoveRef(node);
|
||||
ISetDirty();
|
||||
}
|
||||
else if (message == REFMSG_NODE_MATERIAL_CHANGED ||
|
||||
message == REFMSG_USER_MAT)
|
||||
{
|
||||
if (!node->IsComponent())
|
||||
{
|
||||
node->SetDirty(plMaxNode::kMatDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
}
|
||||
// A node was added to the components target list
|
||||
else if (message == REFMSG_USER_TARGET_ADD)
|
||||
{
|
||||
plMaxNode *target = (plMaxNode*)partID;
|
||||
target->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
// A node was deleted from the components target list
|
||||
else if (message == REFMSG_USER_TARGET_DELETE)
|
||||
{
|
||||
plMaxNode *target = (plMaxNode*)partID;
|
||||
target->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
// A ref maintained by a component PB changed (not just a propagated message
|
||||
// from the ref)
|
||||
else if (message == REFMSG_USER_COMP_REF_CHANGED)
|
||||
{
|
||||
node->SetDirty(plMaxNode::kGeomDirty, true);
|
||||
ISetDirty();
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
bool SceneWatcher::AnyDeleted()
|
||||
{
|
||||
return !fDeleted.empty();
|
||||
}
|
||||
|
||||
SceneWatcher::KeyList& SceneWatcher::GetDeleted()
|
||||
{
|
||||
return fDeleted;
|
||||
}
|
||||
|
||||
const SceneWatcher::NodeList& SceneWatcher::GetWatchNodes()
|
||||
{
|
||||
return fNodes;
|
||||
}
|
||||
|
||||
bool SceneWatcher::AnyDirty()
|
||||
{
|
||||
return fDirty;
|
||||
}
|
||||
|
||||
void SceneWatcher::GetDirty(NodeSet& dirtyNodes)
|
||||
{
|
||||
int size = fNodes.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
plMaxNode *node = fNodes[i];
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
const char *tmp = node ? node->GetName() : nil;
|
||||
#endif
|
||||
// If any dirty flags are set, add to dirty list
|
||||
if (node && node->GetDirty(plMaxNode::kAllDirty))
|
||||
IGetDependents(node, dirtyNodes);
|
||||
}
|
||||
|
||||
fDirty = false;
|
||||
}
|
||||
|
||||
void SceneWatcher::IAddRef(plMaxNode *node)
|
||||
{
|
||||
// Ensure that we don't already ref this node
|
||||
if (FindRef(node) != -1)
|
||||
return;
|
||||
|
||||
// Make a ref
|
||||
int size = fNodes.size();
|
||||
fNodes.resize(size+1);
|
||||
MakeRefByID(FOREVER, size, node);
|
||||
}
|
||||
|
||||
void SceneWatcher::IRemoveRef(plMaxNode *node)
|
||||
{
|
||||
// Delete the reference if it's in our list
|
||||
int i = FindRef(node);
|
||||
|
||||
if (i != -1)
|
||||
{
|
||||
// Clear the node data, in case it is undeleted later
|
||||
// (when it will be invalid)
|
||||
node->ClearData(nil, nil);
|
||||
node->SetDirty(plMaxNode::kAllDirty, true);
|
||||
|
||||
// We can never really delete this reference because the user may "undo"
|
||||
// and cause it to come back, which just sets the reference again.
|
||||
fNodes[i] = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::IAddNodeRecur(plMaxNode *node)
|
||||
{
|
||||
IAddRef(node);
|
||||
|
||||
// If a node is dirty, make sure to set the dirty flag (since nodes may have
|
||||
// been dirtied in a previous run but not reconverted yet).
|
||||
if (node->GetDirty(plMaxNode::kAllDirty))
|
||||
fDirty = true;
|
||||
|
||||
for (int i = 0; i < node->NumberOfChildren(); ++i)
|
||||
{
|
||||
plMaxNode *childNode = (plMaxNode*)node->GetChildNode(i);
|
||||
IAddNodeRecur(childNode);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::INotify(void *param, NotifyInfo *info)
|
||||
{
|
||||
SceneWatcher *inst = (SceneWatcher*)param;
|
||||
|
||||
int code = info->intcode;
|
||||
|
||||
// New node was added to the scene, add it to our refs
|
||||
if (code == NOTIFY_NODE_CREATED)
|
||||
{
|
||||
plMaxNode *node = (plMaxNode*)info->callParam;
|
||||
|
||||
// Add a ref to the node and set it to dirty
|
||||
inst->IAddRef(node);
|
||||
node->SetDirty(plMaxNodeBase::kAllDirty, true);
|
||||
inst->ISetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::ISetDirty()
|
||||
{
|
||||
fDirty = true;
|
||||
}
|
||||
|
||||
#include "../MaxComponent/plMiscComponents.h"
|
||||
|
||||
#include "../MaxExport/plExportErrorMsg.h"
|
||||
#include "../MaxExport/plExportProgressBar.h"
|
||||
#include "../MaxComponent/plResponderComponent.h" // Just need the CID
|
||||
|
||||
void SceneWatcher::IGetLogicDependents(plMaxNode *node, NodeSet& nodes)
|
||||
{
|
||||
int attached = node->NumAttachedComponents();
|
||||
for (int i = 0; i < attached; i++)
|
||||
{
|
||||
plComponentBase *comp = node->GetAttachedComponent(i);
|
||||
/*
|
||||
if (comp->ClassID() == ACTIVATOR_CID)
|
||||
{
|
||||
plMaxNodeBase *activatorNode = comp->GetINode();
|
||||
int numResponders = activatorNode->NumAttachedComponents(true);
|
||||
for (int i = 0; i < numResponders; i++)
|
||||
{
|
||||
plComponentBase *responderComp = activatorNode->GetAttachedComponent(i, true);
|
||||
if (responderComp->ClassID() == RESPONDER_CID)
|
||||
{
|
||||
for (int j = 0; j < responderComp->NumTargets(); j++)
|
||||
{
|
||||
plMaxNode *targ = (plMaxNode*)responderComp->GetTarget(j);
|
||||
if (targ && nodes.find(targ) == nodes.end())
|
||||
{
|
||||
nodes.insert(targ);
|
||||
IGetLogicDependents(targ, nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (comp->ClassID() == RESPONDER_CID)
|
||||
{
|
||||
int activatorCnt = ResponderGetActivatorCount(comp);
|
||||
for (int i = 0; i < activatorCnt; i++)
|
||||
{
|
||||
plComponentBase *activator = ResponderGetActivator(comp, i);
|
||||
|
||||
for (int j = 0; j < activator->NumTargets(); j++)
|
||||
{
|
||||
plMaxNode *targ = (plMaxNode*)activator->GetTarget(j);
|
||||
if (targ && nodes.find(targ) == nodes.end())
|
||||
{
|
||||
nodes.insert(targ);
|
||||
IGetLogicDependents(targ, nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWatcher::IGetDependents(plMaxNode *node, NodeSet& nodes)
|
||||
{
|
||||
NodeSet dependents;
|
||||
|
||||
if (node->IsComponent())
|
||||
{
|
||||
plComponentBase *comp = node->ConvertToComponent();
|
||||
|
||||
if (comp->ClassID() == ROOM_CID || comp->ClassID() == PAGEINFO_CID)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < comp->NumTargets(); i++)
|
||||
{
|
||||
plMaxNode *targ = (plMaxNode*)comp->GetTarget(i);
|
||||
if (targ)
|
||||
{
|
||||
dependents.insert(targ);
|
||||
IGetLogicDependents(targ, dependents);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dependents.insert(node);
|
||||
|
||||
IGetLogicDependents(node, dependents);
|
||||
}
|
||||
|
||||
// Bug in VC++?
|
||||
// nodes.insert(dependents.begin(), dependents.end());
|
||||
for (NodeSet::iterator i = dependents.begin(); i != dependents.end(); i++)
|
||||
nodes.insert(*i);
|
||||
}
|
@ -1,93 +1,93 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef SCENE_WATCHER_H
|
||||
#define SCENE_WATCHER_H
|
||||
|
||||
#include "Max.h"
|
||||
#include "notify.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
class plMaxNode;
|
||||
|
||||
class SceneWatcher : public ReferenceMaker
|
||||
{
|
||||
public:
|
||||
typedef std::vector<plMaxNode*> NodeList;
|
||||
typedef std::set<plMaxNode*> NodeSet;
|
||||
typedef std::vector<plKey> KeyList;
|
||||
|
||||
protected:
|
||||
NodeList fNodes;
|
||||
KeyList fDeleted;
|
||||
|
||||
bool fDirty;
|
||||
|
||||
public:
|
||||
SceneWatcher();
|
||||
~SceneWatcher();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// ReferenceMaker functions
|
||||
//
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
BOOL IsRealDependency(ReferenceTarget *rtarg) { return FALSE; }
|
||||
|
||||
// Get all the nodes we're watching
|
||||
const NodeList& GetWatchNodes();
|
||||
|
||||
// Get all the nodes that need to be reconverted
|
||||
bool AnyDirty();
|
||||
void GetDirty(NodeSet& dirtyNodes);
|
||||
|
||||
bool AnyDeleted();
|
||||
KeyList& GetDeleted();
|
||||
|
||||
protected:
|
||||
void IAddRef(plMaxNode *node);
|
||||
void IRemoveRef(plMaxNode *node);
|
||||
|
||||
void IAddNodeRecur(plMaxNode *node);
|
||||
|
||||
// Helpers for GetDirtyNodes
|
||||
void IGetDependents(plMaxNode *node, NodeSet& nodes);
|
||||
void IGetLogicDependents(plMaxNode *node, NodeSet& nodes);
|
||||
|
||||
void ISetDirty();
|
||||
|
||||
static void INotify(void *param, NotifyInfo *info);
|
||||
};
|
||||
|
||||
#endif //SCENE_WATCHER_H
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef SCENE_WATCHER_H
|
||||
#define SCENE_WATCHER_H
|
||||
|
||||
#include "Max.h"
|
||||
#include "notify.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
class plMaxNode;
|
||||
|
||||
class SceneWatcher : public ReferenceMaker
|
||||
{
|
||||
public:
|
||||
typedef std::vector<plMaxNode*> NodeList;
|
||||
typedef std::set<plMaxNode*> NodeSet;
|
||||
typedef std::vector<plKey> KeyList;
|
||||
|
||||
protected:
|
||||
NodeList fNodes;
|
||||
KeyList fDeleted;
|
||||
|
||||
bool fDirty;
|
||||
|
||||
public:
|
||||
SceneWatcher();
|
||||
~SceneWatcher();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// ReferenceMaker functions
|
||||
//
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
BOOL IsRealDependency(ReferenceTarget *rtarg) { return FALSE; }
|
||||
|
||||
// Get all the nodes we're watching
|
||||
const NodeList& GetWatchNodes();
|
||||
|
||||
// Get all the nodes that need to be reconverted
|
||||
bool AnyDirty();
|
||||
void GetDirty(NodeSet& dirtyNodes);
|
||||
|
||||
bool AnyDeleted();
|
||||
KeyList& GetDeleted();
|
||||
|
||||
protected:
|
||||
void IAddRef(plMaxNode *node);
|
||||
void IRemoveRef(plMaxNode *node);
|
||||
|
||||
void IAddNodeRecur(plMaxNode *node);
|
||||
|
||||
// Helpers for GetDirtyNodes
|
||||
void IGetDependents(plMaxNode *node, NodeSet& nodes);
|
||||
void IGetLogicDependents(plMaxNode *node, NodeSet& nodes);
|
||||
|
||||
void ISetDirty();
|
||||
|
||||
static void INotify(void *param, NotifyInfo *info);
|
||||
};
|
||||
|
||||
#endif //SCENE_WATCHER_H
|
||||
|
@ -1,87 +1,87 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plKeyRefSort.h"
|
||||
#include "../pnKeyedObject/plKeyImp.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
std::vector<plKey>* plKeyRefSort::fKeys = nil;
|
||||
std::vector<plKeyRefSort::KeyRefs> plKeyRefSort::fNumRefs;
|
||||
|
||||
int plKeyRefSort::CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys)
|
||||
{
|
||||
int numRefs = 0;
|
||||
|
||||
if (std::find(traversedKeys.begin(), traversedKeys.end(), key) == traversedKeys.end())
|
||||
{
|
||||
traversedKeys.push_back(key);
|
||||
|
||||
plKeyImp* iKey = (plKeyImp*)key;
|
||||
for (int i = 0; i < iKey->GetNumRefs(); i++)
|
||||
{
|
||||
plKey refKey = iKey->GetRef(i);
|
||||
if (std::find(fKeys->begin(), fKeys->end(), refKey) != fKeys->end())
|
||||
numRefs++;
|
||||
|
||||
numRefs += CountRefsRecur(refKey, traversedKeys);
|
||||
}
|
||||
}
|
||||
|
||||
return numRefs;
|
||||
}
|
||||
|
||||
|
||||
class RefComp
|
||||
{
|
||||
public:
|
||||
bool operator() (plKey key1, plKey key2) const
|
||||
{
|
||||
std::vector<plKeyRefSort::KeyRefs>::iterator it1 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key1);
|
||||
std::vector<plKeyRefSort::KeyRefs>::iterator it2 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key2);
|
||||
|
||||
return ((*it1).fNumRefs < (*it2).fNumRefs);
|
||||
}
|
||||
};
|
||||
|
||||
void plKeyRefSort::Sort(std::vector<plKey>* keys)
|
||||
{
|
||||
fKeys = keys;
|
||||
int numKeys = keys->size();
|
||||
fNumRefs.resize(numKeys);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numKeys; i++)
|
||||
{
|
||||
plKey curKey = (*keys)[i];
|
||||
|
||||
std::vector<plKey> traversedKeys;
|
||||
int numRefs = CountRefsRecur(curKey, traversedKeys);
|
||||
|
||||
fNumRefs[i] = KeyRefs(curKey, numRefs);
|
||||
}
|
||||
|
||||
std::sort(fKeys->begin(), fKeys->end(), RefComp());
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plKeyRefSort.h"
|
||||
#include "../pnKeyedObject/plKeyImp.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
std::vector<plKey>* plKeyRefSort::fKeys = nil;
|
||||
std::vector<plKeyRefSort::KeyRefs> plKeyRefSort::fNumRefs;
|
||||
|
||||
int plKeyRefSort::CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys)
|
||||
{
|
||||
int numRefs = 0;
|
||||
|
||||
if (std::find(traversedKeys.begin(), traversedKeys.end(), key) == traversedKeys.end())
|
||||
{
|
||||
traversedKeys.push_back(key);
|
||||
|
||||
plKeyImp* iKey = (plKeyImp*)key;
|
||||
for (int i = 0; i < iKey->GetNumRefs(); i++)
|
||||
{
|
||||
plKey refKey = iKey->GetRef(i);
|
||||
if (std::find(fKeys->begin(), fKeys->end(), refKey) != fKeys->end())
|
||||
numRefs++;
|
||||
|
||||
numRefs += CountRefsRecur(refKey, traversedKeys);
|
||||
}
|
||||
}
|
||||
|
||||
return numRefs;
|
||||
}
|
||||
|
||||
|
||||
class RefComp
|
||||
{
|
||||
public:
|
||||
bool operator() (plKey key1, plKey key2) const
|
||||
{
|
||||
std::vector<plKeyRefSort::KeyRefs>::iterator it1 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key1);
|
||||
std::vector<plKeyRefSort::KeyRefs>::iterator it2 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key2);
|
||||
|
||||
return ((*it1).fNumRefs < (*it2).fNumRefs);
|
||||
}
|
||||
};
|
||||
|
||||
void plKeyRefSort::Sort(std::vector<plKey>* keys)
|
||||
{
|
||||
fKeys = keys;
|
||||
int numKeys = keys->size();
|
||||
fNumRefs.resize(numKeys);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numKeys; i++)
|
||||
{
|
||||
plKey curKey = (*keys)[i];
|
||||
|
||||
std::vector<plKey> traversedKeys;
|
||||
int numRefs = CountRefsRecur(curKey, traversedKeys);
|
||||
|
||||
fNumRefs[i] = KeyRefs(curKey, numRefs);
|
||||
}
|
||||
|
||||
std::sort(fKeys->begin(), fKeys->end(), RefComp());
|
||||
}
|
@ -1,59 +1,59 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include <vector>
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
|
||||
// A really crappy sort of a list of keys from the most referenced key to the least.
|
||||
// This allows you to write out and read in the keys without having to worry about
|
||||
// one referencing another that isn't loaded yet (ie, in the SceneViewer)
|
||||
class plKeyRefSort
|
||||
{
|
||||
protected:
|
||||
class KeyRefs
|
||||
{
|
||||
public:
|
||||
plKey fKey;
|
||||
int fNumRefs;
|
||||
KeyRefs() : fKey(nil), fNumRefs(-1) {}
|
||||
KeyRefs(plKey key, int numRefs) : fKey(key), fNumRefs(numRefs) {}
|
||||
hsBool operator== (const plKey key)
|
||||
{
|
||||
return (fKey == key);
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<plKey>* fKeys;
|
||||
static std::vector<KeyRefs> fNumRefs;
|
||||
|
||||
friend class RefComp;
|
||||
|
||||
static int CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys);
|
||||
|
||||
public:
|
||||
static void Sort(std::vector<plKey>* keys);
|
||||
};
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include <vector>
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
|
||||
// A really crappy sort of a list of keys from the most referenced key to the least.
|
||||
// This allows you to write out and read in the keys without having to worry about
|
||||
// one referencing another that isn't loaded yet (ie, in the SceneViewer)
|
||||
class plKeyRefSort
|
||||
{
|
||||
protected:
|
||||
class KeyRefs
|
||||
{
|
||||
public:
|
||||
plKey fKey;
|
||||
int fNumRefs;
|
||||
KeyRefs() : fKey(nil), fNumRefs(-1) {}
|
||||
KeyRefs(plKey key, int numRefs) : fKey(key), fNumRefs(numRefs) {}
|
||||
hsBool operator== (const plKey key)
|
||||
{
|
||||
return (fKey == key);
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<plKey>* fKeys;
|
||||
static std::vector<KeyRefs> fNumRefs;
|
||||
|
||||
friend class RefComp;
|
||||
|
||||
static int CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys);
|
||||
|
||||
public:
|
||||
static void Sort(std::vector<plKey>* keys);
|
||||
};
|
||||
|
@ -1,277 +1,277 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "plMaxFileData.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
#include "max.h"
|
||||
#include "notify.h"
|
||||
#include "tvnode.h"
|
||||
|
||||
#define PLASMA_FILE_DATA_CID Class_ID(0x255a700a, 0x285279dc)
|
||||
|
||||
// MyControl is derived from StdControl, but has no controller functionality. It simply has some
|
||||
// membervariables and saves these by Load and Save.
|
||||
// EditTrackParams and TrackParamsType are responsible for displaying a user interface (RightClick->Properties)
|
||||
// on the controler. With these functions you can avoid it, having an interface !
|
||||
// As you can see, most of these methods are stubbed. Only Load and Save are implemented
|
||||
// and of course the methods, to access the membervariables.
|
||||
class plMaxFileDataControl : public StdControl
|
||||
{
|
||||
public:
|
||||
SYSTEMTIME fCodeBuildTime;
|
||||
char fBranch[128];
|
||||
|
||||
plMaxFileDataControl()
|
||||
{
|
||||
memset(&fCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
||||
memset(&fBranch, 0, sizeof(fBranch));
|
||||
}
|
||||
|
||||
// Animatable
|
||||
virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim,TCHAR *pname,HWND hParent, IObjParam *ip, DWORD flags){};
|
||||
int TrackParamsType() { return TRACKPARAMS_WHOLE; }
|
||||
virtual void DeleteThis() { delete this; }
|
||||
|
||||
// ReferenceMaker
|
||||
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message)
|
||||
{return REF_DONTCARE;}
|
||||
|
||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
||||
void GetClassName(TSTR& s) {s = "blah";}
|
||||
|
||||
// Control methods
|
||||
RefTargetHandle Clone(RemapDir& remap) { return TRACKED_NEW plMaxFileDataControl(); }
|
||||
void Copy(Control *from) {}
|
||||
virtual BOOL IsReplaceable() { return FALSE; }
|
||||
|
||||
// StdControl methods
|
||||
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE){}
|
||||
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
|
||||
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type){}
|
||||
void *CreateTempValue() {return NULL;}
|
||||
void DeleteTempValue(void *val) {}
|
||||
void ApplyValue(void *val, void *delta) {}
|
||||
void MultiplyValue(void *val, float m) {}
|
||||
|
||||
// MyControl methods
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
};
|
||||
|
||||
#define MAXFILE_DATA_CHUNK 1001
|
||||
static const UInt8 kVersion = 1;
|
||||
|
||||
IOResult plMaxFileDataControl::Load(ILoad *iload)
|
||||
{
|
||||
ULONG nb;
|
||||
IOResult res;
|
||||
while (IO_OK==(res=iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == MAXFILE_DATA_CHUNK)
|
||||
{
|
||||
UInt8 version = 0;
|
||||
res = iload->Read(&version, sizeof(UInt8), &nb);
|
||||
res = iload->Read(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
||||
|
||||
int branchLen = 0;
|
||||
iload->Read(&branchLen, sizeof(int), &nb);
|
||||
iload->Read(&fBranch, branchLen, &nb);
|
||||
}
|
||||
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plMaxFileDataControl::Save(ISave *isave)
|
||||
{
|
||||
ULONG nb;
|
||||
isave->BeginChunk(MAXFILE_DATA_CHUNK);
|
||||
|
||||
isave->Write(&kVersion, sizeof(kVersion), &nb);
|
||||
isave->Write(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
||||
|
||||
int branchLen = strlen(fBranch)+1;
|
||||
isave->Write(&branchLen, sizeof(int), &nb);
|
||||
isave->Write(&fBranch, branchLen, &nb);
|
||||
|
||||
isave->EndChunk();
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
class MaxFileDataClassDesc : public ClassDesc
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return FALSE; }
|
||||
void* Create(BOOL loading) { return TRACKED_NEW plMaxFileDataControl; }
|
||||
const TCHAR* ClassName() { return _T("MaxFileData"); }
|
||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
||||
const TCHAR* Category() { return _T(""); }
|
||||
};
|
||||
MaxFileDataClassDesc gMaxFileDataClassDesc;
|
||||
ClassDesc *GetMaxFileDataDesc() { return &gMaxFileDataClassDesc; }
|
||||
|
||||
// This functions searches for Trackviewnode and the Controller and creates one, if none is present.
|
||||
plMaxFileDataControl *GetMaxFileData(bool& created)
|
||||
{
|
||||
plMaxFileDataControl *pCtrl = NULL;
|
||||
ITrackViewNode *tvNode = NULL;
|
||||
ITrackViewNode *tvRoot = GetCOREInterface()->GetTrackViewRootNode();
|
||||
|
||||
int i = tvRoot->FindItem(PLASMA_FILE_DATA_CID);
|
||||
if (i < 0)
|
||||
{
|
||||
created = true;
|
||||
|
||||
tvNode = CreateITrackViewNode();
|
||||
|
||||
// This method adds the Node with the specific Title (e.g. "My Settings")
|
||||
tvRoot->AddNode(tvNode, "Plasma Globals", PLASMA_FILE_DATA_CID);
|
||||
pCtrl = (plMaxFileDataControl*)CreateInstance(CTRL_FLOAT_CLASS_ID, PLASMA_FILE_DATA_CID);
|
||||
|
||||
TSTR s;
|
||||
pCtrl->GetClassName(s);
|
||||
|
||||
|
||||
// This adds the controller
|
||||
tvNode->AddController(pCtrl, s, PLASMA_FILE_DATA_CID);
|
||||
tvNode->HideChildren(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
created = false;
|
||||
|
||||
tvNode = tvRoot->GetNode(i);
|
||||
pCtrl = (plMaxFileDataControl*)tvNode->GetController(PLASMA_FILE_DATA_CID);
|
||||
}
|
||||
|
||||
return pCtrl;
|
||||
}
|
||||
|
||||
static SYSTEMTIME gThisCodeBuildTime;
|
||||
static char gThisBranch[128];
|
||||
|
||||
static void PrintTime(SYSTEMTIME& time, char* buf)
|
||||
{
|
||||
sprintf(buf, "%d/%d/%d %d:%02d %s", time.wMonth, time.wDay, time.wYear,
|
||||
(time.wHour <= 12) ? time.wHour : time.wHour-12,
|
||||
time.wMinute,
|
||||
(time.wHour < 12 || time.wHour == 24) ? "AM" : "PM");
|
||||
}
|
||||
|
||||
static void NotifyProc(void *param, NotifyInfo *info)
|
||||
{
|
||||
if (info->intcode == NOTIFY_FILE_POST_OPEN)
|
||||
{
|
||||
bool created;
|
||||
plMaxFileDataControl* data = GetMaxFileData(created);
|
||||
|
||||
if (!created)
|
||||
{
|
||||
FILETIME fileTime, pluginTime;
|
||||
SystemTimeToFileTime(&gThisCodeBuildTime, &pluginTime);
|
||||
SystemTimeToFileTime(&data->fCodeBuildTime, &fileTime);
|
||||
|
||||
if (CompareFileTime(&fileTime, &pluginTime) > 0)
|
||||
{
|
||||
if (hsMessageBox_SuppressPrompts)
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
|
||||
strcpy(buf, "This file was last saved with plugins stamped:\n\n");
|
||||
|
||||
char timeBuf[128];
|
||||
PrintTime(data->fCodeBuildTime, timeBuf);
|
||||
strcat(buf, timeBuf);
|
||||
strcat(buf, "\n");
|
||||
strcat(buf, data->fBranch);
|
||||
|
||||
strcat(buf, "\n\nThese plugins are stamped:\n\n");
|
||||
|
||||
PrintTime(gThisCodeBuildTime, timeBuf);
|
||||
strcat(buf, timeBuf);
|
||||
strcat(buf, "\n");
|
||||
strcat(buf, gThisBranch);
|
||||
|
||||
strcat(buf,
|
||||
"\n\nNew features may have been added to the newer plugins,\n"
|
||||
"so saving this file could cause data to be lost.");
|
||||
|
||||
MessageBox(GetCOREInterface()->GetMAXHWnd(), buf, "Plugin Warning", MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(data->fBranch, gThisBranch);
|
||||
memcpy(&data->fCodeBuildTime, &gThisCodeBuildTime, sizeof(SYSTEMTIME));
|
||||
}
|
||||
}
|
||||
|
||||
static void IGetString(int resID, char *destBuffer, int size)
|
||||
{
|
||||
HRSRC rsrc = ::FindResource(hInstance, MAKEINTRESOURCE(resID), RT_RCDATA);
|
||||
|
||||
if (rsrc != NULL)
|
||||
{
|
||||
HGLOBAL handle = ::LoadResource(hInstance, rsrc);
|
||||
|
||||
if (handle != NULL)
|
||||
{
|
||||
char* str = (char*)::LockResource(handle);
|
||||
strncpy(destBuffer, str, size);
|
||||
UnlockResource(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitMaxFileData()
|
||||
{
|
||||
memset(&gThisCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
||||
|
||||
// Date
|
||||
char buf[128];
|
||||
IGetString(1000, buf, sizeof(buf) - 1);
|
||||
sscanf(buf, "%hu/%hu/%hu", &gThisCodeBuildTime.wMonth, &gThisCodeBuildTime.wDay, &gThisCodeBuildTime.wYear);
|
||||
|
||||
// Time
|
||||
IGetString(1001, buf, sizeof(buf) - 1);
|
||||
sscanf(buf, "%hu:%hu", &gThisCodeBuildTime.wHour, &gThisCodeBuildTime.wMinute);
|
||||
|
||||
if (strstr(buf, "PM") != nil)
|
||||
{
|
||||
gThisCodeBuildTime.wHour += 12;
|
||||
}
|
||||
|
||||
IGetString(1002, gThisBranch, sizeof(gThisBranch) - 1);
|
||||
|
||||
RegisterNotification(NotifyProc, 0, NOTIFY_FILE_POST_OPEN);
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "plMaxFileData.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
#include "max.h"
|
||||
#include "notify.h"
|
||||
#include "tvnode.h"
|
||||
|
||||
#define PLASMA_FILE_DATA_CID Class_ID(0x255a700a, 0x285279dc)
|
||||
|
||||
// MyControl is derived from StdControl, but has no controller functionality. It simply has some
|
||||
// membervariables and saves these by Load and Save.
|
||||
// EditTrackParams and TrackParamsType are responsible for displaying a user interface (RightClick->Properties)
|
||||
// on the controler. With these functions you can avoid it, having an interface !
|
||||
// As you can see, most of these methods are stubbed. Only Load and Save are implemented
|
||||
// and of course the methods, to access the membervariables.
|
||||
class plMaxFileDataControl : public StdControl
|
||||
{
|
||||
public:
|
||||
SYSTEMTIME fCodeBuildTime;
|
||||
char fBranch[128];
|
||||
|
||||
plMaxFileDataControl()
|
||||
{
|
||||
memset(&fCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
||||
memset(&fBranch, 0, sizeof(fBranch));
|
||||
}
|
||||
|
||||
// Animatable
|
||||
virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim,TCHAR *pname,HWND hParent, IObjParam *ip, DWORD flags){};
|
||||
int TrackParamsType() { return TRACKPARAMS_WHOLE; }
|
||||
virtual void DeleteThis() { delete this; }
|
||||
|
||||
// ReferenceMaker
|
||||
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message)
|
||||
{return REF_DONTCARE;}
|
||||
|
||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
||||
void GetClassName(TSTR& s) {s = "blah";}
|
||||
|
||||
// Control methods
|
||||
RefTargetHandle Clone(RemapDir& remap) { return TRACKED_NEW plMaxFileDataControl(); }
|
||||
void Copy(Control *from) {}
|
||||
virtual BOOL IsReplaceable() { return FALSE; }
|
||||
|
||||
// StdControl methods
|
||||
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE){}
|
||||
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
|
||||
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type){}
|
||||
void *CreateTempValue() {return NULL;}
|
||||
void DeleteTempValue(void *val) {}
|
||||
void ApplyValue(void *val, void *delta) {}
|
||||
void MultiplyValue(void *val, float m) {}
|
||||
|
||||
// MyControl methods
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
};
|
||||
|
||||
#define MAXFILE_DATA_CHUNK 1001
|
||||
static const UInt8 kVersion = 1;
|
||||
|
||||
IOResult plMaxFileDataControl::Load(ILoad *iload)
|
||||
{
|
||||
ULONG nb;
|
||||
IOResult res;
|
||||
while (IO_OK==(res=iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == MAXFILE_DATA_CHUNK)
|
||||
{
|
||||
UInt8 version = 0;
|
||||
res = iload->Read(&version, sizeof(UInt8), &nb);
|
||||
res = iload->Read(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
||||
|
||||
int branchLen = 0;
|
||||
iload->Read(&branchLen, sizeof(int), &nb);
|
||||
iload->Read(&fBranch, branchLen, &nb);
|
||||
}
|
||||
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plMaxFileDataControl::Save(ISave *isave)
|
||||
{
|
||||
ULONG nb;
|
||||
isave->BeginChunk(MAXFILE_DATA_CHUNK);
|
||||
|
||||
isave->Write(&kVersion, sizeof(kVersion), &nb);
|
||||
isave->Write(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb);
|
||||
|
||||
int branchLen = strlen(fBranch)+1;
|
||||
isave->Write(&branchLen, sizeof(int), &nb);
|
||||
isave->Write(&fBranch, branchLen, &nb);
|
||||
|
||||
isave->EndChunk();
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
class MaxFileDataClassDesc : public ClassDesc
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return FALSE; }
|
||||
void* Create(BOOL loading) { return TRACKED_NEW plMaxFileDataControl; }
|
||||
const TCHAR* ClassName() { return _T("MaxFileData"); }
|
||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
|
||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; }
|
||||
const TCHAR* Category() { return _T(""); }
|
||||
};
|
||||
MaxFileDataClassDesc gMaxFileDataClassDesc;
|
||||
ClassDesc *GetMaxFileDataDesc() { return &gMaxFileDataClassDesc; }
|
||||
|
||||
// This functions searches for Trackviewnode and the Controller and creates one, if none is present.
|
||||
plMaxFileDataControl *GetMaxFileData(bool& created)
|
||||
{
|
||||
plMaxFileDataControl *pCtrl = NULL;
|
||||
ITrackViewNode *tvNode = NULL;
|
||||
ITrackViewNode *tvRoot = GetCOREInterface()->GetTrackViewRootNode();
|
||||
|
||||
int i = tvRoot->FindItem(PLASMA_FILE_DATA_CID);
|
||||
if (i < 0)
|
||||
{
|
||||
created = true;
|
||||
|
||||
tvNode = CreateITrackViewNode();
|
||||
|
||||
// This method adds the Node with the specific Title (e.g. "My Settings")
|
||||
tvRoot->AddNode(tvNode, "Plasma Globals", PLASMA_FILE_DATA_CID);
|
||||
pCtrl = (plMaxFileDataControl*)CreateInstance(CTRL_FLOAT_CLASS_ID, PLASMA_FILE_DATA_CID);
|
||||
|
||||
TSTR s;
|
||||
pCtrl->GetClassName(s);
|
||||
|
||||
|
||||
// This adds the controller
|
||||
tvNode->AddController(pCtrl, s, PLASMA_FILE_DATA_CID);
|
||||
tvNode->HideChildren(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
created = false;
|
||||
|
||||
tvNode = tvRoot->GetNode(i);
|
||||
pCtrl = (plMaxFileDataControl*)tvNode->GetController(PLASMA_FILE_DATA_CID);
|
||||
}
|
||||
|
||||
return pCtrl;
|
||||
}
|
||||
|
||||
static SYSTEMTIME gThisCodeBuildTime;
|
||||
static char gThisBranch[128];
|
||||
|
||||
static void PrintTime(SYSTEMTIME& time, char* buf)
|
||||
{
|
||||
sprintf(buf, "%d/%d/%d %d:%02d %s", time.wMonth, time.wDay, time.wYear,
|
||||
(time.wHour <= 12) ? time.wHour : time.wHour-12,
|
||||
time.wMinute,
|
||||
(time.wHour < 12 || time.wHour == 24) ? "AM" : "PM");
|
||||
}
|
||||
|
||||
static void NotifyProc(void *param, NotifyInfo *info)
|
||||
{
|
||||
if (info->intcode == NOTIFY_FILE_POST_OPEN)
|
||||
{
|
||||
bool created;
|
||||
plMaxFileDataControl* data = GetMaxFileData(created);
|
||||
|
||||
if (!created)
|
||||
{
|
||||
FILETIME fileTime, pluginTime;
|
||||
SystemTimeToFileTime(&gThisCodeBuildTime, &pluginTime);
|
||||
SystemTimeToFileTime(&data->fCodeBuildTime, &fileTime);
|
||||
|
||||
if (CompareFileTime(&fileTime, &pluginTime) > 0)
|
||||
{
|
||||
if (hsMessageBox_SuppressPrompts)
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
|
||||
strcpy(buf, "This file was last saved with plugins stamped:\n\n");
|
||||
|
||||
char timeBuf[128];
|
||||
PrintTime(data->fCodeBuildTime, timeBuf);
|
||||
strcat(buf, timeBuf);
|
||||
strcat(buf, "\n");
|
||||
strcat(buf, data->fBranch);
|
||||
|
||||
strcat(buf, "\n\nThese plugins are stamped:\n\n");
|
||||
|
||||
PrintTime(gThisCodeBuildTime, timeBuf);
|
||||
strcat(buf, timeBuf);
|
||||
strcat(buf, "\n");
|
||||
strcat(buf, gThisBranch);
|
||||
|
||||
strcat(buf,
|
||||
"\n\nNew features may have been added to the newer plugins,\n"
|
||||
"so saving this file could cause data to be lost.");
|
||||
|
||||
MessageBox(GetCOREInterface()->GetMAXHWnd(), buf, "Plugin Warning", MB_OK | MB_ICONEXCLAMATION);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(data->fBranch, gThisBranch);
|
||||
memcpy(&data->fCodeBuildTime, &gThisCodeBuildTime, sizeof(SYSTEMTIME));
|
||||
}
|
||||
}
|
||||
|
||||
static void IGetString(int resID, char *destBuffer, int size)
|
||||
{
|
||||
HRSRC rsrc = ::FindResource(hInstance, MAKEINTRESOURCE(resID), RT_RCDATA);
|
||||
|
||||
if (rsrc != NULL)
|
||||
{
|
||||
HGLOBAL handle = ::LoadResource(hInstance, rsrc);
|
||||
|
||||
if (handle != NULL)
|
||||
{
|
||||
char* str = (char*)::LockResource(handle);
|
||||
strncpy(destBuffer, str, size);
|
||||
UnlockResource(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitMaxFileData()
|
||||
{
|
||||
memset(&gThisCodeBuildTime, 0, sizeof(SYSTEMTIME));
|
||||
|
||||
// Date
|
||||
char buf[128];
|
||||
IGetString(1000, buf, sizeof(buf) - 1);
|
||||
sscanf(buf, "%hu/%hu/%hu", &gThisCodeBuildTime.wMonth, &gThisCodeBuildTime.wDay, &gThisCodeBuildTime.wYear);
|
||||
|
||||
// Time
|
||||
IGetString(1001, buf, sizeof(buf) - 1);
|
||||
sscanf(buf, "%hu:%hu", &gThisCodeBuildTime.wHour, &gThisCodeBuildTime.wMinute);
|
||||
|
||||
if (strstr(buf, "PM") != nil)
|
||||
{
|
||||
gThisCodeBuildTime.wHour += 12;
|
||||
}
|
||||
|
||||
IGetString(1002, gThisBranch, sizeof(gThisBranch) - 1);
|
||||
|
||||
RegisterNotification(NotifyProc, 0, NOTIFY_FILE_POST_OPEN);
|
||||
}
|
||||
|
@ -1,26 +1,26 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
void InitMaxFileData();
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
void InitMaxFileData();
|
||||
|
@ -1,51 +1,51 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plPluginClient.h"
|
||||
#include "plPluginApp.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
|
||||
plClient *plPluginApp::Startup(char *pCmdLine)
|
||||
{
|
||||
// Create the client
|
||||
fClient = new plPluginClient;
|
||||
|
||||
// disable networking always
|
||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kDisabled);
|
||||
// and set local triggers
|
||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kLocalTriggers);
|
||||
|
||||
return fClient;
|
||||
}
|
||||
|
||||
void plPluginApp::Shutdown()
|
||||
{
|
||||
// Destroy the client
|
||||
if (fClient)
|
||||
{
|
||||
fClient->Shutdown();
|
||||
fClient = nil;
|
||||
}
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plPluginClient.h"
|
||||
#include "plPluginApp.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
|
||||
plClient *plPluginApp::Startup(char *pCmdLine)
|
||||
{
|
||||
// Create the client
|
||||
fClient = new plPluginClient;
|
||||
|
||||
// disable networking always
|
||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kDisabled);
|
||||
// and set local triggers
|
||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kLocalTriggers);
|
||||
|
||||
return fClient;
|
||||
}
|
||||
|
||||
void plPluginApp::Shutdown()
|
||||
{
|
||||
// Destroy the client
|
||||
if (fClient)
|
||||
{
|
||||
fClient->Shutdown();
|
||||
fClient = nil;
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,43 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "../../Plasma/Apps/plClient/plApp.h"
|
||||
|
||||
class plPluginClient;
|
||||
|
||||
//
|
||||
// Plugin app class. Creates and destroys the client, leaves the resmanager
|
||||
//
|
||||
class plPluginApp : public plApp
|
||||
{
|
||||
protected:
|
||||
plPluginClient *fClient;
|
||||
|
||||
public:
|
||||
plPluginApp() : fClient(NULL) {}
|
||||
|
||||
virtual plClient *Startup(char *CmdLine);
|
||||
virtual void Shutdown();
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "../../Plasma/Apps/plClient/plApp.h"
|
||||
|
||||
class plPluginClient;
|
||||
|
||||
//
|
||||
// Plugin app class. Creates and destroys the client, leaves the resmanager
|
||||
//
|
||||
class plPluginApp : public plApp
|
||||
{
|
||||
protected:
|
||||
plPluginClient *fClient;
|
||||
|
||||
public:
|
||||
plPluginApp() : fClient(NULL) {}
|
||||
|
||||
virtual plClient *Startup(char *CmdLine);
|
||||
virtual void Shutdown();
|
||||
};
|
@ -1,291 +1,291 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plPluginClient.h"
|
||||
|
||||
#include "../../../Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h"
|
||||
|
||||
#include "hsThread.h"
|
||||
#include "hsSTLStream.h"
|
||||
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include "../plResMgr/plUpdatableResManager.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
// Needed for IEnableProxies
|
||||
#include "plPipeline.h"
|
||||
#include "../plDrawable/plDrawableSpans.h"
|
||||
#include "../pnMessage/plProxyDrawMsg.h"
|
||||
#include "plgDispatch.h"
|
||||
|
||||
#define LOG_SCENEVIWER
|
||||
|
||||
static plUpdatableResManager *GetResMgr()
|
||||
{
|
||||
return (plUpdatableResManager*)hsgResMgr::ResMgr();
|
||||
}
|
||||
|
||||
plUpdatableClient::plUpdatableClient() : fPipeName(nil), fUpdateSignal(nil), fDataPath(nil), fActive(true), fDirty(false)
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog = plStatusLogMgr::GetInstance().CreateStatusLog(25, "SceneViewer",
|
||||
plStatusLog::kDontWriteFile | plStatusLog::kFilledBackground | plStatusLog::kAlignToTop);
|
||||
#endif // LOG_SCENEVIWER
|
||||
}
|
||||
|
||||
plUpdatableClient::~plUpdatableClient()
|
||||
{
|
||||
if (fUpdateSignal)
|
||||
{
|
||||
delete fUpdateSignal;
|
||||
fUpdateSignal = nil;
|
||||
}
|
||||
|
||||
if (fLog)
|
||||
{
|
||||
delete fLog;
|
||||
fLog = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void plUpdatableClient::InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir)
|
||||
{
|
||||
fUpdateSignal = TRACKED_NEW hsSemaphore(0, semaphoreName);
|
||||
fPipeName = pipeName;
|
||||
fDataPath = dir;
|
||||
}
|
||||
|
||||
hsG3DDeviceModeRecord plUpdatableClient::ILoadDevMode(const char* devModeFile)
|
||||
{
|
||||
// Get the usual devmode
|
||||
hsG3DDeviceModeRecord dmr = plClient::ILoadDevMode(devModeFile);
|
||||
|
||||
// Override the mode with a windowed one
|
||||
hsG3DDeviceMode *mode = (hsG3DDeviceMode*)dmr.GetMode();
|
||||
mode->SetColorDepth(0);
|
||||
|
||||
return hsG3DDeviceModeRecord(*dmr.GetDevice(), *mode);
|
||||
}
|
||||
|
||||
#include "../../../Plasma/Apps/plClient/plClientUpdateFormat.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
void plUpdatableClient::IGetUpdate()
|
||||
{
|
||||
// If the semaphore is signaled an update is ready
|
||||
if (fUpdateSignal && fUpdateSignal->Wait(0))
|
||||
{
|
||||
hsNamedPipeStream s;
|
||||
s.Open(fPipeName, "r");
|
||||
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->Clear();
|
||||
static int numUpdates = 0;
|
||||
numUpdates++;
|
||||
fLog->AddLineF(plStatusLog::kBlue, "SceneViewer Update #%d", numUpdates);
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
UInt8 type = s.ReadByte();
|
||||
|
||||
if (type == ClientUpdate::kShutdown)
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->AddLine("Client shutdown");
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
PostMessage(GetWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
else if (type == ClientUpdate::kUpdate)
|
||||
{
|
||||
fDirty = true;
|
||||
|
||||
IEnableProxies(false);
|
||||
|
||||
int i;
|
||||
|
||||
//
|
||||
// Delete the deleted keys
|
||||
//
|
||||
int numDeleted = s.ReadSwap32();
|
||||
std::vector<plKey*> delKeys;
|
||||
delKeys.reserve(numDeleted);
|
||||
|
||||
for (i = 0; i < numDeleted; i++)
|
||||
{
|
||||
plUoid uoid;
|
||||
uoid.Read(&s);
|
||||
plKey *key = hsgResMgr::ResMgr()->FindKey(uoid);
|
||||
hsAssert(key, "Key to delete not found");
|
||||
if (key)
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->AddLineF("Remove: %s", key->GetName());
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
GetResMgr()->RemoveObject(key, false);
|
||||
delKeys.push_back(key);
|
||||
}
|
||||
}
|
||||
|
||||
GetResMgr()->DelayLoad(true);
|
||||
|
||||
//
|
||||
// Read in the changed spans
|
||||
//
|
||||
hsStatusMessage("ReadChangedSpans\n");
|
||||
GetResMgr()->ReadChangedSpans(&s);
|
||||
|
||||
//
|
||||
// Read in the new keys and objects
|
||||
//
|
||||
int numNew = s.ReadSwap32();
|
||||
for (i = 0; i < numNew; i++)
|
||||
{
|
||||
plCreatable *cre = GetResMgr()->ReadCreatable(&s);
|
||||
|
||||
hsKeyedObject *ko = hsKeyedObject::ConvertNoRef(cre);
|
||||
|
||||
#ifdef LOG_SCENEVIWER
|
||||
if (ko)
|
||||
fLog->AddLineF("Read: %s", ko->GetKey()->GetName());
|
||||
else
|
||||
fLog->AddLine("Read: (null)");
|
||||
#endif // LOG_SCENEVIWER
|
||||
}
|
||||
|
||||
GetResMgr()->DelayLoad(false);
|
||||
|
||||
// Clear out any objects that were never reloaded (really deleted)
|
||||
for (i = 0; i < delKeys.size(); i++)
|
||||
{
|
||||
plKey *key = delKeys[i];
|
||||
if (!key->ObjectIsLoaded())
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->AddLineF("Key deleted: %s", key->GetName());
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
GetResMgr()->RemoveObject(key);
|
||||
}
|
||||
}
|
||||
|
||||
IEnableProxies(true);
|
||||
}
|
||||
|
||||
s.Close();
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plUpdatableClient::Init()
|
||||
{
|
||||
if (plClient::Init())
|
||||
{
|
||||
GetResMgr()->ForceLoadDirectory(fDataPath, true);
|
||||
// Page in the SceneViewer now that our key is ready
|
||||
GetResMgr()->PageInSceneViewer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plUpdatableClient::MainLoop()
|
||||
{
|
||||
IGetUpdate();
|
||||
|
||||
if (fActive)
|
||||
return plClient::MainLoop();
|
||||
else
|
||||
{
|
||||
Sleep(100);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#include <direct.h>
|
||||
|
||||
hsBool plUpdatableClient::Shutdown()
|
||||
{
|
||||
if (fDirty && fDataPath)
|
||||
{
|
||||
char oldCwd[MAX_PATH];
|
||||
getcwd(oldCwd, sizeof(oldCwd));
|
||||
|
||||
// Even bigger hack
|
||||
char tempCrap[MAX_PATH];
|
||||
strcpy(tempCrap, fDataPath);
|
||||
tempCrap[strlen(tempCrap)-strlen("dat\\")] = '\0';
|
||||
chdir(tempCrap);
|
||||
|
||||
GetResMgr()->WriteSceneViewer();
|
||||
|
||||
chdir(oldCwd);
|
||||
}
|
||||
|
||||
return plClient::Shutdown();
|
||||
}
|
||||
|
||||
void plUpdatableClient::IEnableProxies(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
// switch back on any drawable proxies
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kAudibleProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kAudible | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kOccluderProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kOccluder | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kPhysicalProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kPhysical | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kLightProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kLight | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// notify any and all drawable proxies to stop drawing...
|
||||
plProxyDrawMsg* nuke = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kAudible
|
||||
| plProxyDrawMsg::kOccluder
|
||||
| plProxyDrawMsg::kPhysical
|
||||
| plProxyDrawMsg::kLight
|
||||
| plProxyDrawMsg::kDestroy);
|
||||
plgDispatch::MsgSend(nuke);
|
||||
}
|
||||
}
|
||||
|
||||
void plUpdatableClient::WindowActivate(bool active)
|
||||
{
|
||||
fActive = active;
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plPluginClient.h"
|
||||
|
||||
#include "../../../Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h"
|
||||
|
||||
#include "hsThread.h"
|
||||
#include "hsSTLStream.h"
|
||||
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include "../plResMgr/plUpdatableResManager.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
// Needed for IEnableProxies
|
||||
#include "plPipeline.h"
|
||||
#include "../plDrawable/plDrawableSpans.h"
|
||||
#include "../pnMessage/plProxyDrawMsg.h"
|
||||
#include "plgDispatch.h"
|
||||
|
||||
#define LOG_SCENEVIWER
|
||||
|
||||
static plUpdatableResManager *GetResMgr()
|
||||
{
|
||||
return (plUpdatableResManager*)hsgResMgr::ResMgr();
|
||||
}
|
||||
|
||||
plUpdatableClient::plUpdatableClient() : fPipeName(nil), fUpdateSignal(nil), fDataPath(nil), fActive(true), fDirty(false)
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog = plStatusLogMgr::GetInstance().CreateStatusLog(25, "SceneViewer",
|
||||
plStatusLog::kDontWriteFile | plStatusLog::kFilledBackground | plStatusLog::kAlignToTop);
|
||||
#endif // LOG_SCENEVIWER
|
||||
}
|
||||
|
||||
plUpdatableClient::~plUpdatableClient()
|
||||
{
|
||||
if (fUpdateSignal)
|
||||
{
|
||||
delete fUpdateSignal;
|
||||
fUpdateSignal = nil;
|
||||
}
|
||||
|
||||
if (fLog)
|
||||
{
|
||||
delete fLog;
|
||||
fLog = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void plUpdatableClient::InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir)
|
||||
{
|
||||
fUpdateSignal = TRACKED_NEW hsSemaphore(0, semaphoreName);
|
||||
fPipeName = pipeName;
|
||||
fDataPath = dir;
|
||||
}
|
||||
|
||||
hsG3DDeviceModeRecord plUpdatableClient::ILoadDevMode(const char* devModeFile)
|
||||
{
|
||||
// Get the usual devmode
|
||||
hsG3DDeviceModeRecord dmr = plClient::ILoadDevMode(devModeFile);
|
||||
|
||||
// Override the mode with a windowed one
|
||||
hsG3DDeviceMode *mode = (hsG3DDeviceMode*)dmr.GetMode();
|
||||
mode->SetColorDepth(0);
|
||||
|
||||
return hsG3DDeviceModeRecord(*dmr.GetDevice(), *mode);
|
||||
}
|
||||
|
||||
#include "../../../Plasma/Apps/plClient/plClientUpdateFormat.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
void plUpdatableClient::IGetUpdate()
|
||||
{
|
||||
// If the semaphore is signaled an update is ready
|
||||
if (fUpdateSignal && fUpdateSignal->Wait(0))
|
||||
{
|
||||
hsNamedPipeStream s;
|
||||
s.Open(fPipeName, "r");
|
||||
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->Clear();
|
||||
static int numUpdates = 0;
|
||||
numUpdates++;
|
||||
fLog->AddLineF(plStatusLog::kBlue, "SceneViewer Update #%d", numUpdates);
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
UInt8 type = s.ReadByte();
|
||||
|
||||
if (type == ClientUpdate::kShutdown)
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->AddLine("Client shutdown");
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
PostMessage(GetWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
else if (type == ClientUpdate::kUpdate)
|
||||
{
|
||||
fDirty = true;
|
||||
|
||||
IEnableProxies(false);
|
||||
|
||||
int i;
|
||||
|
||||
//
|
||||
// Delete the deleted keys
|
||||
//
|
||||
int numDeleted = s.ReadSwap32();
|
||||
std::vector<plKey*> delKeys;
|
||||
delKeys.reserve(numDeleted);
|
||||
|
||||
for (i = 0; i < numDeleted; i++)
|
||||
{
|
||||
plUoid uoid;
|
||||
uoid.Read(&s);
|
||||
plKey *key = hsgResMgr::ResMgr()->FindKey(uoid);
|
||||
hsAssert(key, "Key to delete not found");
|
||||
if (key)
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->AddLineF("Remove: %s", key->GetName());
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
GetResMgr()->RemoveObject(key, false);
|
||||
delKeys.push_back(key);
|
||||
}
|
||||
}
|
||||
|
||||
GetResMgr()->DelayLoad(true);
|
||||
|
||||
//
|
||||
// Read in the changed spans
|
||||
//
|
||||
hsStatusMessage("ReadChangedSpans\n");
|
||||
GetResMgr()->ReadChangedSpans(&s);
|
||||
|
||||
//
|
||||
// Read in the new keys and objects
|
||||
//
|
||||
int numNew = s.ReadSwap32();
|
||||
for (i = 0; i < numNew; i++)
|
||||
{
|
||||
plCreatable *cre = GetResMgr()->ReadCreatable(&s);
|
||||
|
||||
hsKeyedObject *ko = hsKeyedObject::ConvertNoRef(cre);
|
||||
|
||||
#ifdef LOG_SCENEVIWER
|
||||
if (ko)
|
||||
fLog->AddLineF("Read: %s", ko->GetKey()->GetName());
|
||||
else
|
||||
fLog->AddLine("Read: (null)");
|
||||
#endif // LOG_SCENEVIWER
|
||||
}
|
||||
|
||||
GetResMgr()->DelayLoad(false);
|
||||
|
||||
// Clear out any objects that were never reloaded (really deleted)
|
||||
for (i = 0; i < delKeys.size(); i++)
|
||||
{
|
||||
plKey *key = delKeys[i];
|
||||
if (!key->ObjectIsLoaded())
|
||||
{
|
||||
#ifdef LOG_SCENEVIWER
|
||||
fLog->AddLineF("Key deleted: %s", key->GetName());
|
||||
#endif // LOG_SCENEVIWER
|
||||
|
||||
GetResMgr()->RemoveObject(key);
|
||||
}
|
||||
}
|
||||
|
||||
IEnableProxies(true);
|
||||
}
|
||||
|
||||
s.Close();
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plUpdatableClient::Init()
|
||||
{
|
||||
if (plClient::Init())
|
||||
{
|
||||
GetResMgr()->ForceLoadDirectory(fDataPath, true);
|
||||
// Page in the SceneViewer now that our key is ready
|
||||
GetResMgr()->PageInSceneViewer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plUpdatableClient::MainLoop()
|
||||
{
|
||||
IGetUpdate();
|
||||
|
||||
if (fActive)
|
||||
return plClient::MainLoop();
|
||||
else
|
||||
{
|
||||
Sleep(100);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#include <direct.h>
|
||||
|
||||
hsBool plUpdatableClient::Shutdown()
|
||||
{
|
||||
if (fDirty && fDataPath)
|
||||
{
|
||||
char oldCwd[MAX_PATH];
|
||||
getcwd(oldCwd, sizeof(oldCwd));
|
||||
|
||||
// Even bigger hack
|
||||
char tempCrap[MAX_PATH];
|
||||
strcpy(tempCrap, fDataPath);
|
||||
tempCrap[strlen(tempCrap)-strlen("dat\\")] = '\0';
|
||||
chdir(tempCrap);
|
||||
|
||||
GetResMgr()->WriteSceneViewer();
|
||||
|
||||
chdir(oldCwd);
|
||||
}
|
||||
|
||||
return plClient::Shutdown();
|
||||
}
|
||||
|
||||
void plUpdatableClient::IEnableProxies(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
// switch back on any drawable proxies
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kAudibleProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kAudible | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kOccluderProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kOccluder | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kPhysicalProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kPhysical | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kLightProxy)
|
||||
{
|
||||
plProxyDrawMsg* msg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kLight | plProxyDrawMsg::kCreate);
|
||||
plgDispatch::MsgSend(msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// notify any and all drawable proxies to stop drawing...
|
||||
plProxyDrawMsg* nuke = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kAudible
|
||||
| plProxyDrawMsg::kOccluder
|
||||
| plProxyDrawMsg::kPhysical
|
||||
| plProxyDrawMsg::kLight
|
||||
| plProxyDrawMsg::kDestroy);
|
||||
plgDispatch::MsgSend(nuke);
|
||||
}
|
||||
}
|
||||
|
||||
void plUpdatableClient::WindowActivate(bool active)
|
||||
{
|
||||
fActive = active;
|
||||
}
|
||||
|
@ -1,65 +1,65 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plUpdatableClient_h_inc
|
||||
#define plUpdatableClient_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "../../Plasma/Apps/plClient/plClient.h"
|
||||
|
||||
class hsSemaphore;
|
||||
class plStatusLog;
|
||||
|
||||
class plUpdatableClient : public plClient
|
||||
{
|
||||
protected:
|
||||
hsSemaphore *fUpdateSignal;
|
||||
const char *fPipeName;
|
||||
const char *fDataPath;
|
||||
|
||||
bool fActive;
|
||||
bool fDirty;
|
||||
|
||||
plStatusLog *fLog;
|
||||
|
||||
void IEnableProxies(bool enable);
|
||||
void IGetUpdate();
|
||||
|
||||
public:
|
||||
plUpdatableClient();
|
||||
virtual ~plUpdatableClient();
|
||||
|
||||
virtual hsG3DDeviceModeRecord ILoadDevMode(const char* devModeFile);
|
||||
|
||||
virtual hsBool Init();
|
||||
virtual hsBool MainLoop();
|
||||
virtual hsBool Shutdown();
|
||||
|
||||
void InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir);
|
||||
|
||||
virtual void WindowActivate(bool active);
|
||||
};
|
||||
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plUpdatableClient_h_inc
|
||||
#define plUpdatableClient_h_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "../../Plasma/Apps/plClient/plClient.h"
|
||||
|
||||
class hsSemaphore;
|
||||
class plStatusLog;
|
||||
|
||||
class plUpdatableClient : public plClient
|
||||
{
|
||||
protected:
|
||||
hsSemaphore *fUpdateSignal;
|
||||
const char *fPipeName;
|
||||
const char *fDataPath;
|
||||
|
||||
bool fActive;
|
||||
bool fDirty;
|
||||
|
||||
plStatusLog *fLog;
|
||||
|
||||
void IEnableProxies(bool enable);
|
||||
void IGetUpdate();
|
||||
|
||||
public:
|
||||
plUpdatableClient();
|
||||
virtual ~plUpdatableClient();
|
||||
|
||||
virtual hsG3DDeviceModeRecord ILoadDevMode(const char* devModeFile);
|
||||
|
||||
virtual hsBool Init();
|
||||
virtual hsBool MainLoop();
|
||||
virtual hsBool Shutdown();
|
||||
|
||||
void InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir);
|
||||
|
||||
virtual void WindowActivate(bool active);
|
||||
};
|
||||
|
||||
#endif // plUpdatableClient_h_inc
|
Reference in New Issue
Block a user