1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: name.h 4211 2010-04-03 19:59:26Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2010 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 //**
26 //**	Vavoom global name types.
27 //**
28 //**************************************************************************
29 
30 //	Maximum length of a name
31 enum { NAME_SIZE = 64 };
32 
33 //
34 //	VNameEntry
35 //
36 //	Entry in the names table.
37 //
38 struct VNameEntry
39 {
40 	VNameEntry*		HashNext;			//	Next name for this hash list.
41 	vint32			Index;				//	Index of the name.
42 	char			Name[NAME_SIZE];	//	Name value.
43 
44 	friend VStream& operator<<(VStream&, VNameEntry&);
45 	friend VNameEntry* AllocateNameEntry(const char* Name, vint32 Index,
46 		VNameEntry* HashNext);
47 };
48 
49 //
50 //	VName
51 //
52 //	Names are stored as indexes in the global name table. They are stored once
53 // and only once. All names are case-sensitive.
54 //
55 class VName
56 {
57 private:
58 	enum { HASH_SIZE = 4096 };
59 
60 	vint32						Index;
61 
62 	static TArray<VNameEntry*>	Names;
63 	static VNameEntry*			HashTable[HASH_SIZE];
64 	static bool					Initialised;
65 
66 public:
67 	//	Different types of finding a name.
68 	enum ENameFindType
69 	{
70 		Find,		// Find a name, return 0 if it doesn't exist.
71 		Add,		// Find a name, add it if it doesn't exist.
72 		AddLower8,	// Find or add lowercased, max length 8 name.
73 		AddLower,	// Find or add lowercased.
74 	};
75 
76 	//	Constructors.
VName()77 	VName()
78 	{}
VName(EName N)79 	VName(EName N) : Index(N)
80 	{}
81 	VName(const char*, ENameFindType = Add);
82 
83 	//	Ancestors.
84 	const char* operator*() const
85 	{
86 		return Names[Index]->Name;
87 	}
GetIndex()88 	vint32 GetIndex() const
89 	{
90 		return Index;
91 	}
92 
93 	//	Comparison operators.
94 	bool operator==(const VName& Other) const
95 	{
96 		return Index == Other.Index;
97 	}
98 	bool operator!=(const VName& Other) const
99 	{
100 		return Index != Other.Index;
101 	}
102 
103 	//	Global functions.
104 	static void StaticInit();
105 	static void StaticExit();
106 
GetNumNames()107 	static int GetNumNames()
108 	{
109 		return Names.Num();
110 	}
GetEntry(int i)111 	static VNameEntry* GetEntry(int i)
112 	{
113 		return Names[i];
114 	}
SafeString(EName N)115 	static const char* SafeString(EName N)
116 	{
117 		return Initialised ? Names[N]->Name : "Uninitialised";
118 	}
119 };
120 
GetTypeHash(const VName N)121 inline vuint32 GetTypeHash(const VName N)
122 {
123 	return N.GetIndex();
124 }
125