Mostly Harmless

Legacy:DataObject

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UT2003/UT2004 :: Note: DataObject is not part of the stock Unreal Engine 2.0, it is only implemented in UT2003 and UT2004.

DataObjects are an alternative method to Config Vars and .Ini Files for storing information that can be accessed later by the game. They are often a better solution when you need to store a lot of information or you don't want it easily edited from outside the game (ie if you use it to store player progress in a game).

An example of DataObjects in UT2003 would be GameProfile, which is used to store a Single Player profile.

In order to make use of DataObject you need an instance of GameInfo or one of it's subclasses (usually via Level.Game), because the functions required to access DataObjects are all contained in GameInfo.

Variables[edit]

The following variables are passed to the DataObject functions. Here's a quick description of what they mean:

packageName 
This is the name of the package file the object(s) will be saved in. The package is stored in Saves\packageName.uvx
objClass 
This is the class name of the object to be created.
objName 
This is a unique identifier for the stored object, it has to be unique in that package or else it will overwrite existing objects with the same name.

Functions[edit]

The following DataObject related functions are defined in GameInfo.

Manifest GetSavedGames() [native, final] 
This will return an instance of Manifest. Manifest.ManifestEntries is a list of all the Packages in the Saves directory. Note: This is a list of the packages, not the DataObjects they contain.
Object CreateDataObject( class objClass, string objName, string packageName ) [native, final] 
This will create a new DataObject. If successful it will return an instance of the new Object, otherwise it returns None. Note: this does not save the package file to disk.
Object LoadDataObject( class objClass, string objName, string packageName ) [native, final] 
Load an existing DataObject, if the DataObject doesn't exist in the package (or the package doesn't exist) None will be returned.
bool DeleteDataObject( class objClass, string objName, string packageName ) [native, final] 
Delete an existing DataObject from the specified package. This does not remove the package file from the disk. If successful it return True, otherwise False.
AllDataObjects( class objClass, out Object obj, string packageName ) [native, final, iterator] 
List all DataObjects in the specified package.
bool SavePackage( string packageName ) [native, final] 
This will save the package to disk, it will be saved to: Saves\<packagename>.uvx If successful it return True, otherwise False.
bool DeletePackage( string packageName ) [native, final] 
This will delete the complete package from the disk. If successful it return True, otherwise False.

Usage[edit]

The data that can be stored in DataObjects follows the same rules as the Default Properties. You can store the 6 basic data types (int, float, string, name, class, enum) and arrays and structs of the 6 basic data types. But you can't store references to other objects.

It is recommended that you prefix package names so it's easier to identify which packages your code has created (eg "Foo_Package1", "Foo_Package2", and so you don't overwrite packages created by someone elses code.

Example[edit]

A working example, from any class call CreateDataObjects() and ListDataObjects() and check the game log file for the results.

Note: As noted above, the DataObject functions are in GameInfo, so you must pass an instance of GameInfo to these functions for them to be able to access the DataObject functions.

	class'DataObjectTest'.static.CreateDataObjects( Level.Game );
	class'DataObjectTest'.static.ListDataObjects( Level.Game );

TestDataObject.uc[edit]

class TestDataObject extends Object;
 
var string PackageName;
var int ObjectNum;
 
DefaultProperties
{
	PackageName="TestPackage"
	ObjectNum=-1
}

DataObjectTest.uc[edit]

class DataObjectTest extends Actor;
 
var string pkgPrefix;
 
static function CreateDataObjects( GameInfo G )
{
	local TestDataObject CurrentObject;
	local int pNum, oNum;
 
	// Lets create 3 packages containing 3 DataObjects each.
	for ( pNum = 1; pNum < 4; pNum++ )
	{
		for ( oNum = 1; oNum < 4; oNum++ )
		{
			// Create a new DataObject.
			CurrentObject = G.CreateDataObject( class'TestDataObject', "MyDataObject_"$oNum, default.pkgPrefix$pNum );
 
			// If we successfully created a DataObject do something with it.
			if ( CurrentObject != none )
			{
				CurrentObject.PackageName = default.pkgPrefix$pNum;
				CurrentObject.ObjectNum = oNum;
			}
			else
				log( "Error creating TestDataObject", 'DataObjectTest' );
		}
 
		// We've created our DataObjects, so lets save the package.
		if ( G.SavePackage( default.pkgPrefix$pNum ) )
			log( default.pkgPrefix$pNum$" package saved!", 'DataObjectTest' );
		else
			log( "Error saving "$default.pkgPrefix$pNum$" package!", 'DataObjectTest' );
	}
}
 
static function ListDataObjects( GameInfo G )
{
	local Manifest M;
	local int iPrefixLen;
	local int i;
	local TestDataObject CurrentObject;
 
	// Get a list of all the packages in the Saves directory.
	M = G.GetSavedGames();
	iPrefixLen = Len( default.pkgPrefix );
 
	// Run through the list of packages.
	for ( i = 0; i < M.ManifestEntries.Length; i++ )
	{
		// If the package name begins with "DataObjectTest_".
		if ( Left( M.ManifestEntries[i], iPrefixLen ) ~= default.pkgPrefix )
		{
			// Get all the DataObjects from the current package.
			foreach G.AllDataObjects( class'TestDataObject', CurrentObject, M.ManifestEntries[i] )
			{
				// Print out the contents of the DataObject.
				log( "----------------------------------------------------------------------------", 'DataObjectTest' );
				log( "	Package Name:"@M.ManifestEntries[i], 'DataObjectTest' );
				log( "	Object name :"@CurrentObject.Name, 'DataObjectTest' );
				log( "	Object Class:"@CurrentObject.Class, 'DataObjectTest' );
				log( "	ObjectNum   :"@CurrentObject.ObjectNum, 'DataObjectTest' );
				log( "----------------------------------------------------------------------------", 'DataObjectTest' );
 
				// Lets try and delete the DataObject.
				if ( G.DeleteDataObject ( class'TestDataObject', string(CurrentObject.Name), M.ManifestEntries[i] ) )
					log( "DataObject deleted!", 'DataObjectTest' );
				else
					log( "Error deleting DataObject!", 'DataObjectTest' );
			}
		}
 
		// The package is empty now so lets delete it.
		if ( G.DeletePackage( M.ManifestEntries[i] ) )
			log( M.ManifestEntries[i]$" package deleted!", 'DataObjectTest' );
		else
			log( "Error deleting "$M.ManifestEntries[i]$" package!", 'DataObjectTest' );
	}
}
 
DefaultProperties
{
	pkgPrefix="DataObjectTest_"
}

Related Topics[edit]

Discussion[edit]

Fyfe: Almost finished refactoring, just need to finish the intro. Reminder: must link DateObject functions in GameInfo to this page. Done

Fyfe: Refactoring done.