229 lines
5.9 KiB
C++
229 lines
5.9 KiB
C++
|
|
#include "RsGuidMgr.h"
|
|
#include <algorithm>
|
|
#include "comutil.h"
|
|
#include <string>
|
|
#include "ifpmaxdatastore.h"
|
|
|
|
#define RSGUIDMGR_NAME "RsGuidMgr"
|
|
|
|
//---------------------------------------------------------------------------
|
|
// IRsGuidMgr
|
|
//---------------------------------------------------------------------------
|
|
|
|
//Declare the callback function
|
|
static void NodeCreateNotify(void *param, NotifyInfo *info);
|
|
|
|
class IRsGuidMgr : public IRsGuidMgrInterface
|
|
{
|
|
public:
|
|
const TCHAR* GetGuid( RefTargetHandle rtarg );
|
|
void SetGuid( RefTargetHandle rtarg, TCHAR* guidString );
|
|
BOOL HasGuid( RefTargetHandle rtarg );
|
|
void ResetGuid( RefTargetHandle rtarg );
|
|
|
|
void Init()
|
|
{
|
|
// Register the callback
|
|
RegisterNotification(NodeCreateNotify, this, NOTIFY_NODE_CREATED);
|
|
|
|
// // When done, unregister the callback
|
|
// UnRegisterNotification(NodeDeleteNotify, this, NOTIFY_SCENE_PRE_DELETED_NODE);
|
|
}
|
|
|
|
DECLARE_DESCRIPTOR(IRsGuidMgr);
|
|
BEGIN_FUNCTION_MAP;
|
|
FN_1(IRsGuidMgr::em_getGuid, TYPE_STRING, GetGuid, TYPE_REFTARG);
|
|
VFN_2(IRsGuidMgr::em_setGuid, SetGuid, TYPE_REFTARG, TYPE_STRING);
|
|
FN_1(IRsGuidMgr::em_hasGuid, TYPE_BOOL, HasGuid, TYPE_REFTARG);
|
|
VFN_1(IRsGuidMgr::em_resetGuid, ResetGuid, TYPE_REFTARG);
|
|
END_FUNCTION_MAP;
|
|
|
|
private:
|
|
RsGuidAttribData* IRsGuidMgr::GetGuidCustAttrib(Animatable* pAnimatable);
|
|
RsGuidAttribData* IRsGuidMgr::AddGuidCustAttrib(Animatable* pAnimatable);
|
|
};
|
|
|
|
|
|
//Define the callback function
|
|
static void NodeCreateNotify(void *param, NotifyInfo *info){
|
|
// Get the nodes being Created
|
|
INode * pNode = (INode*)info->callParam;
|
|
((IRsGuidMgr*)param)->ResetGuid(pNode);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Instantiation
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
IRsGuidMgr IRsGuidMgrDesc(
|
|
FP_RSGUID_INTERFACE,
|
|
_T(RSGUIDMGR_NAME),
|
|
IDS_RSGUIDMGR_NAME,
|
|
NULL,
|
|
FP_CORE,
|
|
|
|
IRsGuidMgr::em_getGuid, _T("GetGuid"), 0, TYPE_STRING, 0, 1,
|
|
_T("ref_target"), 0, TYPE_REFTARG,
|
|
IRsGuidMgr::em_setGuid, _T("SetGuid"), 0 ,TYPE_VOID, 0, 2,
|
|
_T("ref_target"), 0, TYPE_REFTARG,
|
|
_T("guid"), 0, TYPE_STRING,
|
|
IRsGuidMgr::em_hasGuid, _T("HasGuid"), 0 ,TYPE_BOOL, 0, 1,
|
|
_T("ref_target"), 0, TYPE_REFTARG,
|
|
IRsGuidMgr::em_resetGuid, _T("ResetGuid"), 0 ,TYPE_VOID, 0, 1,
|
|
_T("ref_target"), 0, TYPE_REFTARG,
|
|
end
|
|
);
|
|
|
|
// helpers
|
|
|
|
GUID ParseGuidFromString(TCHAR* guidString)
|
|
{
|
|
const int sizebuffer = 128;
|
|
wchar_t wGuid[sizebuffer];
|
|
size_t wCharsWritten = 0;
|
|
errno_t errorID = mbstowcs_s(&wCharsWritten, wGuid, guidString, sizebuffer);
|
|
if(errorID!=0)
|
|
{
|
|
mprintf(_T("Not been able to set Guid from string %s! Error code %d\n"), guidString, errorID);
|
|
return GUID_NULL;
|
|
}
|
|
|
|
GUID newGuid;
|
|
HRESULT res = CLSIDFromString(wGuid, &newGuid);
|
|
if(sizebuffer!=128 || res != NOERROR)
|
|
{
|
|
mprintf(_T("Not been able to set Guid from string %s\n!"), guidString);
|
|
return GUID_NULL;
|
|
}
|
|
return newGuid;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Implementations
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
const TCHAR* IRsGuidMgr::GetGuid( RefTargetHandle rtarg )
|
|
{
|
|
RsGuidAttribData* pGuidAttr = AddGuidCustAttrib(rtarg);
|
|
if(!pGuidAttr)
|
|
{
|
|
mprintf(_T("Not been able to add Guid container to node\n!"));
|
|
return "";
|
|
}
|
|
if(pGuidAttr->GetGuid()==GUID_NULL)
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// This is a safety catch. Guid should be set on nodecreation.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
ResetGuid(rtarg);
|
|
pGuidAttr = GetGuidCustAttrib(rtarg);
|
|
}
|
|
|
|
TCHAR *guidString = new TCHAR[40];
|
|
pGuidAttr->GetGuidString(guidString);
|
|
return guidString;
|
|
}
|
|
|
|
void IRsGuidMgr::SetGuid( RefTargetHandle rtarg, TCHAR* guidString )
|
|
{
|
|
RsGuidAttribData* pGuidAttr = AddGuidCustAttrib(rtarg);
|
|
if(!pGuidAttr)
|
|
{
|
|
mprintf(_T("Not been able to add Guid container to node\n!"));
|
|
return;
|
|
}
|
|
pGuidAttr->SetGuid(ParseGuidFromString(guidString));
|
|
}
|
|
|
|
BOOL IRsGuidMgr::HasGuid( RefTargetHandle rtarg )
|
|
{
|
|
return (NULL!=GetGuidCustAttrib(rtarg));
|
|
}
|
|
|
|
void IRsGuidMgr::ResetGuid( RefTargetHandle rtarg )
|
|
{
|
|
RsGuidAttribData* pGuidAttr = AddGuidCustAttrib(rtarg);
|
|
if(!pGuidAttr)
|
|
{
|
|
mprintf(_T("Not been able to add Guid container to node\n!"));
|
|
return;
|
|
}
|
|
|
|
IFpMaxDataStore* pAttrs = GetMaxDataStoreInterface();
|
|
INodePtr pNode = dynamic_cast<INodePtr>(rtarg);
|
|
if(pAttrs && pNode)
|
|
{
|
|
TSTR guidString = pAttrs->GetGuidString(pNode);
|
|
if(guidString.Length()>0)
|
|
{
|
|
pGuidAttr->SetGuid(ParseGuidFromString(guidString));
|
|
return;
|
|
}
|
|
}
|
|
|
|
pGuidAttr->ResetGuid();
|
|
}
|
|
|
|
|
|
//
|
|
// name: MaxDataMgr::GetCustAttrib
|
|
// description: Get custom attribute from animatable
|
|
// in: ref = pointer to reference target
|
|
//
|
|
RsGuidAttribData* IRsGuidMgr::GetGuidCustAttrib(Animatable* pAnimatable)
|
|
{
|
|
if(!pAnimatable)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
ICustAttribContainer* pContainer = pAnimatable->GetCustAttribContainer();
|
|
if(pContainer)
|
|
{
|
|
for(s32 i=0; i<pContainer->GetNumCustAttribs(); i++)
|
|
{
|
|
CustAttrib* pCustAttrib = pContainer->GetCustAttrib(i);
|
|
const MCHAR *attrName = pCustAttrib->GetName();
|
|
if(pCustAttrib && !_tcscmp(attrName, _T(RSGUID_NAME)))
|
|
{
|
|
return (RsGuidAttribData*)pCustAttrib;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// name: MaxDataMgr::AddCustAttrib
|
|
// description: Add custom attribute to animatable
|
|
// in: ref = pointer to reference target
|
|
//
|
|
RsGuidAttribData* IRsGuidMgr::AddGuidCustAttrib(Animatable* pAnimatable)
|
|
{
|
|
RsGuidAttribData* pCustAttrib = GetGuidCustAttrib(pAnimatable);
|
|
if(pCustAttrib)
|
|
{
|
|
return pCustAttrib;
|
|
}
|
|
|
|
ICustAttribContainer* pContainer = pAnimatable->GetCustAttribContainer();
|
|
if(pContainer == NULL)
|
|
{
|
|
pAnimatable->AllocCustAttribContainer();
|
|
pContainer = pAnimatable->GetCustAttribContainer();
|
|
}
|
|
if(!pContainer)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pCustAttrib = (RsGuidAttribData*)::CreateInstance(CUST_ATTRIB_CLASS_ID, RSGUID_CLASSID);
|
|
pContainer->AppendCustAttrib(pCustAttrib);
|
|
|
|
return GetGuidCustAttrib(pAnimatable);
|
|
}
|
|
|
|
// HierarchyInterface.cpp
|