Files
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

362 lines
11 KiB
C++

//
// /rageMayaGeoDataSet.h
//
// Copyright (C) 1999-2006 Rockstar Games. All Rights Reserved.
//
#ifndef _RAGEMAYAGEODATASET_H_
#define _RAGEMAYAGEODATASET_H_
#pragma warning(push)
#if _MSC_VER >= 1400
#pragma warning(disable: 4005) // warning C4005: 'strcasecmp' : macro redefinition
// rage\base\src\string\string.h declares strcasecmp, and so does MTypes.h
// but they are currently differenct
#endif
#define REQUIRE_IOSTREAM
#pragma warning(push)
#pragma warning(disable : 4668)
#include <windows.h>
#pragma warning(pop)
#pragma warning(disable : 4702) //Disable the 'unreachable code' warning
#include <algorithm>
#include <list>
#include <map>
#include <string>
#include <vector>
#include "atl/functor.h"
#include "atl/singleton.h"
#include "parsercore/attribute.h"
#include "parsercore/element.h"
#include "parsercore/stream.h"
#include "parser/manager.h"
#include "parser/tree.h"
#include "parser/treenode.h"
#include "vector/vector3.h"
using namespace std;
using namespace rage;
namespace rageGEO
{
//-----------------------------------------------------------------------------
enum GEOPARAMVALUE_TYPE
{
TYPE_INT,
TYPE_FLOAT,
TYPE_BOOL,
TYPE_STRING,
TYPE_VECTOR3,
TYPE_NULL
};
//-----------------------------------------------------------------------------
//PURPOSE : This class represents a value from a GEO type of template file
class GeoParamValueVariant
{
public:
GeoParamValueVariant()
: type(TYPE_NULL)
{};
GeoParamValueVariant(const GeoParamValueVariant& other)
{
*this = other;
}
void SetValue(int val) { type = TYPE_INT; iVal = val; }
void SetValue(float val) { type = TYPE_FLOAT; fVal = val; }
void SetValue(bool val) { type = TYPE_BOOL; bVal = val; }
void SetValue(const char* val) { type = TYPE_STRING; sVal = val; }
void SetValue(const Vector3& val) { type = TYPE_VECTOR3; v3Val = val; }
int GetIntValue() { Assert(type == TYPE_INT); return iVal; }
float GetFloatValue() { Assert(type == TYPE_FLOAT); return fVal; }
bool GetBoolValue() { Assert(type == TYPE_BOOL); return bVal; }
const char* GetStringValue() { Assert(type == TYPE_STRING); return sVal.c_str(); }
const Vector3& GetVector3Value() { Assert(type == TYPE_VECTOR3); return v3Val; }
GEOPARAMVALUE_TYPE GetType() const { return type; }
public:
static GeoParamValueVariant nullGeoParamValue;
private:
int iVal;
float fVal;
bool bVal;
string sVal;
Vector3 v3Val;
GEOPARAMVALUE_TYPE type;
};
//-----------------------------------------------------------------------------
//PURPOSE : This class represents a path to a node in the GEO Template/Type
//hierarchy.
//Paths can be specified in the following forms
//
// To reference a node at the root level of a GEO Type or Template:
// (Type Name)
//
// To reference a nested GEO type or template node
// (Type Name)/(Node)/(Node)
// i.e. Saloon/BarRoom/Bar
//
// To reference a particluar element in an array of contained GEOs
// (Type Name)/(Node)[index]
// i.e. Saloon/BarRoom/BarStool[3]
//
class GeoPath
{
private:
class GeoPathSection
{
public:
GeoPathSection()
: m_Index(-1)
{};
GeoPathSection(const char* name, int index)
: m_Name(name)
, m_Index(index)
{};
bool IsArraySection() const
{
if(m_Index == -1)
return false;
else
return true;
}
const char* GetName() const { return m_Name.c_str(); }
void SetName(const char* name) { m_Name = name; }
int GetArrayIndex() const { return m_Index; }
void SetArrayIndex(int idx) { m_Index = idx; }
private:
string m_Name;
int m_Index;
};
public:
GeoPath() {};
GeoPath(const GeoPath& other)
{
*this = other;
}
//PURPOSE: Initalize the GeoPath object, parsing the supplied path
bool Init(const char* path);
//PURPOSE: Returns the root type or template name the path references
const char* GetRootName() const { return m_RootName.c_str(); }
//PURPOSE: Returns the number of "sections" specified in the GEO Path
// i.e. Saloon/Rooms, would have the root type name, plus 1 "section"
int GetNumSections() const { return m_PathSections.size(); }
//PURPOSE: Returns the name of the specified section of the path
const char* GetSectionName(int idx) const { Assert(idx<(int)m_PathSections.size()); return m_PathSections[idx].GetName(); }
//PURPOSE: Returns the index of the specified section of the path
int GetSectionArrayIndex(int idx) const { Assert(idx<(int)m_PathSections.size()); return m_PathSections[idx].GetArrayIndex(); }
//PURPOSE: Returns a boolean value indicating whether the specified section is an array section or not.
bool IsSectionArray(int idx) const { Assert(idx<(int)m_PathSections.size()); return m_PathSections[idx].IsArraySection(); }
//PURPOSE: Returns the GEO path in the full string form
const char* GetPathAsString() const { return m_PathString.c_str(); };
inline bool operator==(const GeoPath& other);
inline void operator=(const GeoPath& other);
private:
string m_PathString;
string m_RootName;
vector<GeoPathSection> m_PathSections;
};
bool GeoPath::operator==(const GeoPath& other)
{
return (m_PathString == other.m_PathString);
}
void GeoPath::operator=(const GeoPath& other)
{
m_PathString = other.m_PathString;
m_RootName = other.m_RootName;
m_PathSections.clear();
std::copy(other.m_PathSections.begin(), other.m_PathSections.end(), m_PathSections.begin());
}
//-----------------------------------------------------------------------------
//PURPOSE: Represents a class used for caching parameter values that have been
//queried for through the GeoDataSet class
class GeoDataSetCache
{
public:
enum CACHEPATH
{
GEO_TYPE_DIR = 0,
GEO_TEMPLATE_DIR,
CACHE_PATH_COUNT
};
GeoDataSetCache()
{
m_CachPathChangeHandles[GEO_TYPE_DIR] = INVALID_HANDLE_VALUE;
m_CachPathChangeHandles[GEO_TEMPLATE_DIR] = INVALID_HANDLE_VALUE;
};
~GeoDataSetCache()
{
FlushCache();
}
bool InitializePaths(const char* typeFilePath, const char* templateFilePath);
GeoParamValueVariant FindNode(const GeoPath& gp, const char* paramName);
GeoParamValueVariant FindNode(const char* geoPath, const char* paramName);
void CacheNode(const GeoPath& gp, const char* paramName, GeoParamValueVariant& val);
void CacheNode(const char* geoPath, const char* paramName, GeoParamValueVariant& val);
private:
void FlushCache();
string BuildCacheKey(const char* geoPathStr, const char* paramName) const;
private:
HANDLE m_CachPathChangeHandles[CACHE_PATH_COUNT];
typedef std::map<std::string, GeoParamValueVariant> GEOPARAMCACHE;
GEOPARAMCACHE m_ParamCache;
};
//-----------------------------------------------------------------------------
//PURPOSE : This is a singleton class that is used to query data directly from GEO
//Template and GEO Type files.
class rageMayaGeoDataSet
{
friend class GeoDataSetCache;
public:
typedef rage::Functor1<const char*> rageGeoDataSetMsgFtor;
private:
struct GeoTypePathMember
{
GeoTypePathMember()
: m_Index(-1)
{};
GeoTypePathMember(const string& name, int index)
: m_Name(name)
, m_Index(index)
{};
string m_Name;
int m_Index;
};
struct searchItem
{
searchItem(string name, bool isTemplate)
: m_name(name)
, m_bIsTemplate(isTemplate)
{};
string m_name;
bool m_bIsTemplate;
};
public:
~rageMayaGeoDataSet();
//PURPOSE: Initializes the root GEO Type and GEO Template paths where the respective files are stored
void InitializePaths(const char* pTypePath, const char* pTemplatePath);
//PURPOSE: Returns the full path to the GEO type files.
const char* GetTypeRootPath() const { return m_TypeRootPath.c_str(); }
//PURPOSE: Returns the full path to the GEO template files.
const char* GetTemplateRootPath() const { return m_TemplateRootPath.c_str(); }
//PURPOSE: Returns a boolean value indicating whether the supplied parameter can be found in the specified type
bool IsGEOParamAvailable(const char* typeName, const char* paramName, GEOPARAMVALUE_TYPE paramType);
//PURPOSE: The following methods retrieve the specified parameter value as the data type indicated by the method name.
bool GetGEOParamValueAsInt(const char* typeName, const char* paramName, int& retVal);
bool GetGEOParamValueAsFloat(const char* typeName, const char* paramName, float& retVal);
bool GetGEOParamValueAsBool(const char* typeName, const char* paramName, bool& retVal);
bool GetGEOParamValueAsVec3(const char* typeName, const char* paramName, Vector3& retVal);
bool GetGEOParamValueAsString(const char* typeName, const char* paramName, string& retVal);
//PURPOSE: The following methods allow the client of the GEODataSet object to specify callbacks that can be used
// to display info, warning, or error messages.
void SetInfoMsgFtor( rageGeoDataSetMsgFtor fn ) { m_InfoMsgFtor = fn; }
void SetWarnMsgFtor( rageGeoDataSetMsgFtor fn ) { m_WarnMsgFtor = fn; }
void SetErrorMsgFtor( rageGeoDataSetMsgFtor fn ) { m_ErrorMsgFtor = fn; }
protected:
rageMayaGeoDataSet();
private:
bool ParseGEOTypeName(const char* typeName, vector<GeoTypePathMember>& pathMembers);
GeoParamValueVariant TreeNodeToVariant(parTreeNode *pNode, bool bIsTemplateNode, GEOPARAMVALUE_TYPE paramType);
GeoParamValueVariant GetGEOParamValue(const char* typeName, const char* paramName, GEOPARAMVALUE_TYPE paramType);
GeoParamValueVariant FindGEOParamNodeInType(GeoPath& geoTypePath,
const char* paramName,
GEOPARAMVALUE_TYPE paramType,
searchItem& curItem,
list<searchItem>& searchQueue);
GeoParamValueVariant FindGEOParamNodeInTemplate(const char* paramName,
GEOPARAMVALUE_TYPE paramType,
searchItem& curItem,
list<searchItem>& searchQueue);
bool FindGeoParameterNode(parTreeNode *pRootNode,
const char *paramPath,
GEOPARAMVALUE_TYPE paramType,
bool bIsTemplate,
GeoParamValueVariant &retVal);
void DisplayInfoMsg(const char* format, ...);
void DisplayWarnMsg(const char* format, ...);
void DisplayErrorMsg(const char* format, ...);
private:
string m_TypeRootPath;
string m_TemplateRootPath;
GeoDataSetCache m_ParamCache;
rageGeoDataSetMsgFtor m_InfoMsgFtor;
rageGeoDataSetMsgFtor m_WarnMsgFtor;
rageGeoDataSetMsgFtor m_ErrorMsgFtor;
};
//-----------------------------------------------------------------------------
typedef atSingleton<rageMayaGeoDataSet> rageMayaGeoDataSetSingleton;
#define GEODATASET ::rageGEO::rageMayaGeoDataSetSingleton::InstanceRef()
#define INIT_GEODATASET ::rageGEO::rageMayaGeoDataSetSingleton::Instantiate()
#define SHUTDOWN_GEODATASET ::rageGEO::rageMayaGeoDataSetSingleton::Destroy()
//-----------------------------------------------------------------------------
} //End namespace rageGEO
#endif //_RAGEMAYAGEODATASET_H_