Beginnings of the "pass everything using a native type wrapper" console code.

- ConsoleValue class is now the base value class.
- ConsoleValueRef is now used to supply function parameters. Values are disposable.
- Script functions return values instead of just strings where possible.
- Variables can be disposable strings
- Bytecode changed

Fix the issues with console method parameters and fields which prevented missions from loading.
This commit is contained in:
James Urquhart 2012-09-23 09:59:48 +01:00
parent 394d87cd54
commit 38c8e52c1d
68 changed files with 1511 additions and 529 deletions

View file

@ -151,7 +151,7 @@ class Namespace
void clear();
///
const char *execute( S32 argc, const char** argv, ExprEvalState* state );
const char *execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
/// Return a one-line documentation text string for the function.
String getBriefDescription( String* outRemainingDocText = NULL ) const;
@ -275,7 +275,7 @@ class Namespace
typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
extern char *typeValueEmpty;
class Dictionary
{
@ -283,16 +283,9 @@ public:
struct Entry
{
enum
{
TypeInternalInt = -3,
TypeInternalFloat = -2,
TypeInternalString = -1,
};
StringTableEntry name;
ConsoleValue value;
Entry *nextEntry;
S32 type;
typedef Signal<void()> NotifySignal;
@ -306,72 +299,42 @@ public:
/// Whether this is a constant that cannot be assigned to.
bool mIsConstant;
protected:
// NOTE: This is protected to ensure no one outside
// of this structure is messing with it.
#pragma warning( push )
#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
// An variable is either a real dynamic type or
// its one exposed from C++ using a data pointer.
//
// We use this nameless union and struct setup
// to optimize the memory usage.
union
{
struct
{
char *sval;
U32 ival; // doubles as strlen when type is TypeInternalString
F32 fval;
U32 bufferLen;
};
struct
{
/// The real data pointer.
void *dataPtr;
/// The enum lookup table for enumerated types.
const EnumTable *enumTable;
};
};
#pragma warning( pop ) // C4201
public:
Entry() {
name = NULL;
notify = NULL;
nextEntry = NULL;
mUsage = NULL;
mIsConstant = false;
value.init();
}
Entry(StringTableEntry name);
~Entry();
U32 getIntValue()
{
if(type <= TypeInternalString)
return ival;
else
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
Entry *mNext;
void reset() {
name = NULL;
value.cleanup();
if ( notify )
delete notify;
}
F32 getFloatValue()
inline U32 getIntValue()
{
if(type <= TypeInternalString)
return fval;
else
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
return value.getIntValue();
}
const char *getStringValue()
inline F32 getFloatValue()
{
if(type == TypeInternalString)
return sval;
if(type == TypeInternalFloat)
return Con::getData(TypeF32, &fval, 0);
else if(type == TypeInternalInt)
return Con::getData(TypeS32, &ival, 0);
else
return Con::getData(type, dataPtr, 0, enumTable);
return value.getFloatValue();
}
inline const char *getStringValue()
{
return value.getStringValue();
}
void setIntValue(U32 val)
@ -381,23 +344,8 @@ public:
Con::errorf( "Cannot assign value to constant '%s'.", name );
return;
}
if(type <= TypeInternalString)
{
fval = (F32)val;
ival = val;
if(sval != typeValueEmpty)
{
dFree(sval);
sval = typeValueEmpty;
}
type = TypeInternalInt;
}
else
{
const char *dptr = Con::getData(TypeS32, &val, 0);
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
}
value.setIntValue(val);
// Fire off the notification if we have one.
if ( notify )
@ -411,30 +359,29 @@ public:
Con::errorf( "Cannot assign value to constant '%s'.", name );
return;
}
if(type <= TypeInternalString)
{
fval = val;
ival = static_cast<U32>(val);
if(sval != typeValueEmpty)
{
dFree(sval);
sval = typeValueEmpty;
}
type = TypeInternalFloat;
}
else
{
const char *dptr = Con::getData(TypeF32, &val, 0);
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
}
value.setFloatValue(val);
// Fire off the notification if we have one.
if ( notify )
notify->trigger();
}
void setStringValue(const char *value);
void setStringValue(const char *newValue)
{
if( mIsConstant )
{
Con::errorf( "Cannot assign value to constant '%s'.", name );
return;
}
value.setStringValue(newValue);
// Fire off the notification if we have one.
if ( notify )
notify->trigger();
}
};
struct HashTableData
@ -473,6 +420,8 @@ public:
void setVariable(StringTableEntry name, const char *value);
const char *getVariable(StringTableEntry name, bool *valid = NULL);
S32 getIntVariable(StringTableEntry name, bool *valid = NULL);
F32 getFloatVariable(StringTableEntry name, bool *entValid = NULL);
U32 getCount() const
{