Skip to content
Browse files

JSON++, layout reading

- ozCore
  * String::ensureCapacity() improved, uses realloc
  * JSON::setXXX() replaced by ctors, add() and include() updated accordingly
- matrix
  * layout writing improved, void write( JSON* ) -> JSON write(), better file
    structure
- client
  * loading layouts, "-e" option
  • Loading branch information...
1 parent 3cf6674 commit a04b92fb86d9859fe579d2746ff29ea970af7ed0 @ducakar committed Mar 2, 2013
View
2 ChangeLog.md
@@ -9,7 +9,7 @@
+ new Set template class: Map with arbitrary elements instead of key-value pairs
+ HashIndex and HashString merged into new HashMap template class with an arbitrary key type
+ new HashSet template class: hashtable of arbitrary elements instead of key-value pairs
- * String: construction from numbers, number parsing functions
+ * String: construction from numbers, new number parsing functions
* new Mat33 class
* SIMD support for linear algebra classes
* new SpinLock class
View
2 src/builder/Builder.cc
@@ -715,7 +715,7 @@ int Builder::main( int argc, char** argv )
{
String invocationName = String::fileBaseName( argv[0] );
- config.setObject();
+ config = JSON( JSON::OBJECT );
bool doCat = false;
bool doUI = false;
View
20 src/client/Client.cc
@@ -68,6 +68,7 @@ void Client::printUsage( const char* invocationName )
" -v Print verbose log messages to terminal.\n"
" -l Skip main menu and load the last autosaved game.\n"
" -i <mission> Skip main menu and start mission <mission>.\n"
+ " -e <layout> Edit world <layout> file. Create a new one if non-existent.\n"
" -t <num> Exit after <num> seconds (can be a floating-point number) and\n"
" use 42 as the random seed. Useful for benchmarking.\n"
" -L <lang> Use language <lang>. Should match a subdirectory name in\n"
@@ -88,11 +89,12 @@ int Client::init( int argc, char** argv )
String prefix;
String language;
String mission;
+ String layoutFile;
bool doAutoload = false;
optind = 1;
int opt;
- while( ( opt = getopt( argc, argv, "vli:t:L:p:h?" ) ) >= 0 ) {
+ while( ( opt = getopt( argc, argv, "vlie:t:L:p:h?" ) ) >= 0 ) {
switch( opt ) {
case 'v': {
Log::showVerbose = true;
@@ -106,6 +108,10 @@ int Client::init( int argc, char** argv )
mission = optarg;
break;
}
+ case 'e': {
+ layoutFile = optarg;
+ break;
+ }
case 't': {
const char* end;
benchmarkTime = float( String::parseDouble( optarg, &end ) );
@@ -266,8 +272,7 @@ int Client::init( int argc, char** argv )
Log::println( "Invalid configuration file version, configuration will be cleaned and written"
" upon exit" );
- config.clear();
- config.setObject();
+ config = JSON( JSON::OBJECT );
config.add( "_version", OZ_VERSION );
config["_version"];
}
@@ -276,7 +281,7 @@ int Client::init( int argc, char** argv )
Log::println( "No configuration file, default configuration will be used and written upon"
" exit" );
- config.setObject();
+ config = JSON( JSON::OBJECT );
config.add( "_version", OZ_VERSION );
config["_version"];
}
@@ -473,8 +478,10 @@ int Client::init( int argc, char** argv )
Stage::nextStage = nullptr;
- if( !mission.isEmpty() ) {
- gameStage.mission = mission;
+ if( !mission.isEmpty() || !layoutFile.isEmpty() ) {
+ gameStage.layoutFile = File( File::NATIVE, layoutFile );
+ gameStage.mission = mission;
+
stage = &gameStage;
}
else if( doAutoload ) {
@@ -573,7 +580,6 @@ int Client::main()
bool isAlive = true;
bool isActive = true;
-
// time passed form start of the frame
uint timeSpent;
uint timeNow;
View
5 src/client/GameStage.cc
@@ -119,10 +119,7 @@ void GameStage::readLayout()
void GameStage::writeLayout() const
{
- JSON json;
- json.setObject();
-
- matrix.write( &json );
+ JSON json = matrix.write();
Log::print( "Saving layout to %s ...", layoutFile.path().cstr() );
View
18 src/client/Input.cc
@@ -327,8 +327,7 @@ void Input::loadKeyMap( const JSON& keyConfig )
JSON Input::keyMapToJSON() const
{
- JSON keyConfig;
- keyConfig.setObject();
+ JSON keyConfig( JSON::OBJECT );
#if SDL_MAJOR_VERSION < 2
keyConfig.add( "modifier0", SDL_GetKeyName( modifier0 ) );
@@ -339,7 +338,7 @@ JSON Input::keyMapToJSON() const
#endif
for( int i = KEY_NONE + 1; i < KEY_MAX; ++i ) {
- JSON& key = keyConfig.addArray( KEY_NAMES[i] );
+ JSON& key = keyConfig.add( KEY_NAMES[i], JSON::ARRAY );
for( int j = 0; j < 2; ++j ) {
if( keyMap[i][j] != KEY_NONE ) {
@@ -562,12 +561,12 @@ void Input::init()
if( !String::equals( inputConfig["_version"].get( "" ), OZ_VERSION ) ) {
configExists = false;
- inputConfig.setNull();
+ inputConfig = JSON();
}
if( !String::equals( inputConfig["_backend"].get( "" ), BACKEND ) ) {
configExists = false;
- inputConfig.setNull();
+ inputConfig = JSON();
}
const JSON& mouseConfig = inputConfig["mouse"];
@@ -651,15 +650,14 @@ void Input::destroy()
Log::print( "Writing Input configuration to '%s' ...", configFile.path().cstr() );
- JSON inputConfig;
- inputConfig.setObject();
+ JSON inputConfig( JSON::OBJECT );
inputConfig.add( "_version", OZ_VERSION );
inputConfig.add( "_backend", BACKEND );
- JSON& mouseConfig = inputConfig.addObject( "mouse" );
- JSON& keyboardConfig = inputConfig.addObject( "keyboard" );
- JSON& keyMapConfig = inputConfig.addObject( "bindings" );
+ JSON& mouseConfig = inputConfig.add( "mouse", JSON::OBJECT );
+ JSON& keyboardConfig = inputConfig.add( "keyboard", JSON::OBJECT );
+ JSON& keyMapConfig = inputConfig.add( "bindings", JSON::OBJECT );
mouseConfig.add( "sensitivity.x", mouseSensX );
mouseConfig.add( "sensitivity.y", mouseSensY );
View
16 src/client/Lua.cc
@@ -44,14 +44,20 @@ void Lua::staticCall( const char* functionName )
hard_assert( l_gettop() == 0 );
l_getglobal( functionName );
- l_pcall( 0, 0 );
-
- if( l_gettop() != 0 ) {
- Log::println( "Lua[C] in %s(): %s", functionName, l_tostring( -1 ) );
- System::bell();
+ if( l_type( 1 ) == LUA_TNIL ) {
l_pop( 1 );
}
+ else {
+ l_pcall( 0, 0 );
+
+ if( l_gettop() != 0 ) {
+ Log::println( "Lua[C] in %s(): %s", functionName, l_tostring( -1 ) );
+ System::bell();
+
+ l_pop( 1 );
+ }
+ }
}
void Lua::update()
View
4 src/client/Lua.hh
@@ -35,10 +35,12 @@ namespace client
class Lua : public common::Lua
{
- public:
+ private:
void staticCall( const char* functionName );
+ public:
+
void update();
void create( const char* missionPath );
View
4 src/client/Profile.cc
@@ -45,7 +45,7 @@ void Profile::init()
bool configExists = profileConfig.load( profileFile );
if( profileConfig.isNull() ) {
- profileConfig.setObject();
+ profileConfig = JSON( JSON::OBJECT );
}
name = profileConfig["name"].get( "" );
@@ -82,7 +82,7 @@ void Profile::init()
profileConfig.add( "class", "beast" );
profileConfig.add( "weaponItem", 0 );
- JSON& itemsConfig = profileConfig.addArray( "items" );
+ JSON& itemsConfig = profileConfig.add( "items", JSON::ARRAY );
itemsConfig.add( "beast$plasmagun" );
itemsConfig.add( "nvGoggles" );
View
3 src/client/ui/MainMenu.cc
@@ -29,6 +29,7 @@
#include <client/GameStage.hh>
#include <client/MenuStage.hh>
#include <client/OpenGL.hh>
+#include <client/Window.hh>
#include <client/BuildInfo.hh>
#include <client/ui/Style.hh>
#include <client/ui/MissionMenu.hh>
@@ -108,6 +109,8 @@ static void openWeb( Button* )
_Exit( 0 );
}
#endif
+
+ window.minimise();
}
static void quit( Button* )
View
78 src/matrix/Bot.cc
@@ -419,22 +419,14 @@ void Bot::onUpdate()
{
const BotClass* clazz = static_cast<const BotClass*>( this->clazz );
- Dynamic* cargoObj = nullptr;
- Weapon* weaponObj = nullptr;
+ Dynamic* cargoObj = static_cast<Dynamic*>( orbis.obj( cargo ) );
+ Weapon* weaponObj = static_cast<Weapon*>( orbis.obj( weapon ) );
- if( cargo >= 0 ) {
- cargoObj = static_cast<Dynamic*>( orbis.objects[cargo] );
-
- if( cargoObj == nullptr ) {
- releaseCargo();
- }
+ if( cargoObj == nullptr ) {
+ releaseCargo();
}
- if( weapon >= 0 ) {
- weaponObj = static_cast<Weapon*>( orbis.objects[weapon] );
-
- if( weaponObj == nullptr ) {
- weapon = -1;
- }
+ if( weaponObj == nullptr ) {
+ weapon = -1;
}
// Sanity checks.
@@ -1207,21 +1199,21 @@ Bot::Bot( const BotClass* clazz_, const JSON& json ) :
h = json["h"].asFloat();
v = json["v"].asFloat();
- actions = json["actions"].asInt();
- oldActions = json["oldActions"].asInt();
- instrument = json["instrument"].asInt();
- container = json["container"].asInt();
+ actions = 0;
+ oldActions = 0;
+ instrument = -1;
+ container = -1;
state = json["state"].asInt();
- oldState = json["oldState"].asInt();
+ oldState = state;
stamina = json["stamina"].asFloat();
step = json["step"].asFloat();
stairRate = json["stairRate"].asFloat();
cargo = json["cargo"].asInt();
weapon = json["weapon"].asInt();
grabHandle = json["grabHandle"].asFloat();
- meleeTime = json["meleeTime"].asFloat();
+ meleeTime = 0.0f;
camZ = state & Bot::CROUCHING_BIT ? clazz_->crouchCamZ : clazz_->camZ;
@@ -1261,32 +1253,28 @@ void Bot::write( OutputStream* ostream ) const
ostream->writeString( mindFunc );
}
-void Bot::write( JSON* json ) const
+JSON Bot::write() const
{
- Dynamic::write( json );
-
- json->add( "dim", dim );
-
- json->add( "h", h );
- json->add( "v", v );
- json->add( "actions", actions );
- json->add( "oldActions", oldActions );
- json->add( "instrument", instrument );
- json->add( "container", container );
-
- json->add( "state", state );
- json->add( "oldState", oldState );
- json->add( "stamina", stamina );
- json->add( "step", step );
- json->add( "stairRate", stairRate );
-
- json->add( "cargo", cargo );
- json->add( "weapon", weapon );
- json->add( "grabHandle", grabHandle );
- json->add( "meleeTime", meleeTime );
-
- json->add( "name", name );
- json->add( "mindFunc", mindFunc );
+ JSON json = Dynamic::write();
+
+ json.add( "dim", dim );
+
+ json.add( "h", h );
+ json.add( "v", v );
+
+ json.add( "state", state );
+ json.add( "stamina", stamina );
+ json.add( "step", step );
+ json.add( "stairRate", stairRate );
+
+ json.add( "cargo", orbis.objIndex( cargo ) );
+ json.add( "weapon", orbis.objIndex( weapon ) );
+ json.add( "grabHandle", grabHandle );
+
+ json.add( "name", name );
+ json.add( "mindFunc", mindFunc );
+
+ return json;
}
void Bot::readUpdate( InputStream* )
View
2 src/matrix/Bot.hh
@@ -222,7 +222,7 @@ class Bot : public Dynamic
explicit Bot( const BotClass* clazz, const JSON& json );
void write( OutputStream* ostream ) const override;
- void write( JSON* json ) const override;
+ JSON write() const override;
void readUpdate( InputStream* istream ) override;
void writeUpdate( OutputStream* ostream ) const override;
View
18 src/matrix/Caelum.cc
@@ -61,5 +61,23 @@ void Caelum::write( OutputStream* ostream ) const
ostream->writeFloat( time );
}
+void Caelum::read( const JSON& json )
+{
+ heading = json["heading"].get( 0.0f );
+ period = json["period"].get( 86400.0f );
+ time = json["time"].get( 0.0f );
+}
+
+JSON Caelum::write() const
+{
+ JSON json( JSON::OBJECT );
+
+ json.add( "heading", heading );
+ json.add( "period", period );
+ json.add( "time", time );
+
+ return json;
+}
+
}
}
View
3 src/matrix/Caelum.hh
@@ -46,6 +46,9 @@ class Caelum
void read( InputStream* istream );
void write( OutputStream* ostream ) const;
+ void read( const JSON& json );
+ JSON write() const;
+
};
}
View
20 src/matrix/Dynamic.cc
@@ -108,16 +108,18 @@ void Dynamic::write( OutputStream* ostream ) const
ostream->writeFloat( depth );
}
-void Dynamic::write( JSON* json ) const
+JSON Dynamic::write() const
{
- Object::write( json );
-
- json->add( "velocity", velocity );
- json->add( "momentum", momentum );
- json->add( "floor", floor );
- json->add( "parent", parent );
- json->add( "lower", lower );
- json->add( "depth", depth );
+ JSON json = Object::write();
+
+ json.add( "velocity", velocity );
+ json.add( "momentum", momentum );
+ json.add( "floor", floor );
+ json.add( "parent", orbis.objIndex( parent ) );
+ json.add( "lower", orbis.objIndex( lower ) );
+ json.add( "depth", depth );
+
+ return json;
}
void Dynamic::readUpdate( InputStream* )
View
2 src/matrix/Dynamic.hh
@@ -59,7 +59,7 @@ class Dynamic : public Object
explicit Dynamic( const DynamicClass* clazz, const JSON& json );
void write( OutputStream* ostream ) const override;
- void write( JSON* json ) const override;
+ JSON write() const override;
void readUpdate( InputStream* istream ) override;
void writeUpdate( OutputStream* ostream ) const override;
View
18 src/matrix/Frag.cc
@@ -72,20 +72,26 @@ Frag::Frag( const FragPool* pool_, const JSON& json )
elasticity = pool->elasticity;
}
-void Frag::write( OutputStream* ostream )
+void Frag::write( OutputStream* ostream ) const
{
ostream->writeInt( index );
ostream->writePoint( p );
ostream->writeVec3( velocity );
ostream->writeFloat( life );
}
-void Frag::write( JSON* json )
+JSON Frag::write() const
{
- json->add( "index", index );
- json->add( "p", p );
- json->add( "velocity", velocity );
- json->add( "life", life );
+ JSON json( JSON::OBJECT );
+
+ json.add( "pool", pool->name );
+
+ json.add( "index", index );
+ json.add( "p", p );
+ json.add( "velocity", velocity );
+ json.add( "life", life );
+
+ return json;
}
void Frag::readUpdate( InputStream* )
View
4 src/matrix/Frag.hh
@@ -82,8 +82,8 @@ class Frag
explicit Frag( const FragPool* pool, InputStream* istream );
explicit Frag( const FragPool* pool, const JSON& json );
- void write( OutputStream* ostream );
- void write( JSON* json );
+ void write( OutputStream* ostream ) const;
+ JSON write() const;
void readUpdate( InputStream* istream );
void writeUpdate( OutputStream* ostream );
View
6 src/matrix/Matrix.cc
@@ -183,13 +183,15 @@ void Matrix::read( const JSON& json )
Log::println( "}" );
}
-void Matrix::write( JSON* json ) const
+JSON Matrix::write() const
{
Log::print( "Writing Matrix ..." );
- orbis.write( json );
+ JSON json = orbis.write();
Log::printEnd( " OK" );
+
+ return json;
}
void Matrix::load()
View
2 src/matrix/Matrix.hh
@@ -53,7 +53,7 @@ class Matrix
void write( OutputStream* ostream ) const;
void read( const JSON& json );
- void write( JSON* json ) const;
+ JSON write() const;
void load();
void unload();
View
37 src/matrix/Object.cc
@@ -157,18 +157,6 @@ Object::Object( const ObjectClass* clazz_, const JSON& json )
swap( dim.x, dim.y );
}
- const JSON& eventsJSON = json["events"];
-
- int nEvents = eventsJSON.length();
- for( int i = 0; i < nEvents; ++i ) {
- const JSON& eventJSON = eventsJSON[i];
-
- int id = eventJSON["id"].asInt();
- float intensity = eventJSON["intensity"].asFloat();
-
- addEvent( id, intensity );
- }
-
if( clazz->nItems != 0 ) {
items.allocate( clazz->nItems );
@@ -202,29 +190,26 @@ void Object::write( OutputStream* ostream ) const
}
}
-void Object::write( JSON* json ) const
+JSON Object::write() const
{
- json->add( "p", p );
- json->add( "index", index );
- json->add( "flags", flags );
- json->add( "life", life );
+ JSON json( JSON::OBJECT );
- JSON& eventsJSON = json->addArray( "events" );
+ json.add( "class", clazz->name );
- foreach( event, events.citer() ) {
- JSON& eventJSON = eventsJSON.addObject();
+ json.add( "p", p );
+ json.add( "index", index );
+ json.add( "flags", flags );
+ json.add( "life", life );
- eventJSON.add( "id", event->id );
- eventJSON.add( "intensity", event->intensity );
- }
-
- JSON& itemsJSON = json->addArray( "items" );
+ JSON& itemsJSON = json.add( "items", JSON::ARRAY );
if( clazz->nItems != 0 ) {
foreach( item, items.citer() ) {
- itemsJSON.add( *item );
+ itemsJSON.add( orbis.objIndex( *item ) );
}
}
+
+ return json;
}
void Object::readUpdate( InputStream* )
View
2 src/matrix/Object.hh
@@ -329,7 +329,7 @@ class Object : public AABB
explicit Object( const ObjectClass* clazz, const JSON& json );
virtual void write( OutputStream* ostream ) const;
- virtual void write( JSON* json ) const;
+ virtual JSON write() const;
virtual void readUpdate( InputStream* istream );
virtual void writeUpdate( OutputStream* ostream ) const;
View
163 src/matrix/Orbis.cc
@@ -323,22 +323,19 @@ void Orbis::read( InputStream* istream )
lua.read( istream );
- terra.read( istream );
caelum.read( istream );
+ terra.read( istream );
int nStructs = istream->readInt();
int nObjects = istream->readInt();
int nFrags = istream->readInt();
- String bspName;
- String className;
- String poolName;
-
for( int i = 0; i < nStructs; ++i ) {
Struct* str = nullptr;
- bspName = istream->readString();
- if( !bspName.isEmpty() ) {
+ const char* bspName = istream->readString();
+
+ if( !String::isEmpty( bspName ) ) {
const BSP* bsp = liber.bsp( bspName );
const_cast<BSP*>( bsp )->request();
@@ -350,8 +347,9 @@ void Orbis::read( InputStream* istream )
for( int i = 0; i < nObjects; ++i ) {
Object* obj = nullptr;
- className = istream->readString();
- if( !className.isEmpty() ) {
+ const char* className = istream->readString();
+
+ if( !String::isEmpty( className ) ) {
const ObjectClass* clazz = liber.objClass( className );
obj = clazz->create( istream );
@@ -368,8 +366,9 @@ void Orbis::read( InputStream* istream )
for( int i = 0; i < nFrags; ++i ) {
Frag* frag = nullptr;
- poolName = istream->readString();
- if( !poolName.isEmpty() ) {
+ const char* poolName = istream->readString();
+
+ if( !String::isEmpty( poolName ) ) {
const FragPool* pool = liber.fragPool( poolName );
frag = new Frag( pool, istream );
@@ -424,8 +423,8 @@ void Orbis::write( OutputStream* ostream ) const
{
lua.write( ostream );
- terra.write( ostream );
caelum.write( ostream );
+ terra.write( ostream );
ostream->writeInt( structs.length() );
ostream->writeInt( objects.length() );
@@ -514,10 +513,8 @@ void Orbis::read( const JSON& json )
{
hard_assert( structs.length() == 0 && objects.length() == 0 && frags.length() == 0 );
-// lua.read( istream );
-
-// terra.read( istream );
-// caelum.read( istream );
+ caelum.read( json["caelum"] );
+ terra.read( json["terra"] );
String bspName;
String className;
@@ -579,148 +576,60 @@ void Orbis::read( const JSON& json )
}
frags.add( frag );
}
-
- const JSON& strFreedIndicesFreeingJSON = json["strFreedIndicesFreeing"];
- foreach( i, strFreedIndicesFreeingJSON.arrayCIter() ) {
- strFreedIndices[freeing].add( i->asInt() );
- }
-
- const JSON& objFreedIndicesFreeingJSON = json["objFreedIndicesFreeing"];
- foreach( i, objFreedIndicesFreeingJSON.arrayCIter() ) {
- objFreedIndices[freeing].add( i->asInt() );
- }
-
- const JSON& fragFreedIndicesFreeingJSON = json["fragFreedIndicesFreeing"];
- foreach( i, fragFreedIndicesFreeingJSON.arrayCIter() ) {
- fragFreedIndices[freeing].add( i->asInt() );
- }
-
- const JSON& strFreedIndicesWaitingJSON = json["strFreedIndicesWaiting"];
- foreach( i, strFreedIndicesWaitingJSON.arrayCIter() ) {
- strFreedIndices[waiting].add( i->asInt() );
- }
-
- const JSON& objFreedIndicesWaitingJSON = json["objFreedIndicesWaiting"];
- foreach( i, objFreedIndicesWaitingJSON.arrayCIter() ) {
- objFreedIndices[waiting].add( i->asInt() );
- }
-
- const JSON& fragFreedIndicesWaitingJSON = json["fragFreedIndicesWaiting"];
- foreach( i, fragFreedIndicesWaitingJSON.arrayCIter() ) {
- fragFreedIndices[waiting].add( i->asInt() );
- }
-
- const JSON& strAvailableIndicesJSON = json["strAvailableIndices"];
- foreach( i, strAvailableIndicesJSON.arrayCIter() ) {
- strAvailableIndices.add( i->asInt() );
- }
-
- const JSON& objAvailableIndicesJSON = json["objAvailableIndices"];
- foreach( i, objAvailableIndicesJSON.arrayCIter() ) {
- objAvailableIndices.add( i->asInt() );
- }
-
- const JSON& fragAvailableIndicesJSON = json["fragAvailableIndices"];
- foreach( i, fragAvailableIndicesJSON.arrayCIter() ) {
- fragAvailableIndices.add( i->asInt() );
- }
}
-void Orbis::write( JSON* json ) const
+JSON Orbis::write() const
{
-// lua.write( ostream );
+ JSON json( JSON::OBJECT );
-// terra.write( ostream );
-// caelum.write( ostream );
+ json.add( "caelum", caelum.write() );
+ json.add( "terra", terra.write() );
Struct* str;
Object* obj;
Frag* frag;
- JSON& structsJSON = json->addArray( "structs" );
+ JSON& structsJSON = json.add( "structs", JSON::ARRAY );
for( int i = 0; i < structs.length(); ++i ) {
str = structs[i];
- JSON& structJSON = structsJSON.addObject();
-
- if( str != nullptr ) {
- structJSON.add( "bsp", str->bsp->name );
- str->write( &structJSON );
+ if( str == nullptr ) {
+ structsJSON.add( JSON::OBJECT );
+ }
+ else {
+ structsJSON.add( str->write() );
}
}
- JSON& objectsJSON = json->addArray( "objects" );
+ JSON& objectsJSON = json.add( "objects", JSON::ARRAY );
for( int i = 0; i < objects.length(); ++i ) {
obj = objects[i];
- JSON& objectJSON = objectsJSON.addObject();
-
- if( obj != nullptr ) {
- objectJSON.add( "class", obj->clazz->name );
- obj->write( &objectJSON );
+ if( obj == nullptr ) {
+ objectsJSON.add( JSON::OBJECT );
+ }
+ else {
+ JSON& objectJSON = objectsJSON.add( obj->write() );
objectJSON.add( "isCut", obj->cell == nullptr );
}
}
- JSON& fragsJSON = json->addArray( "frags" );
+ JSON& fragsJSON = json.add( "frags", JSON::ARRAY );
for( int i = 0; i < frags.length(); ++i ) {
frag = frags[i];
- JSON& fragJSON = fragsJSON.addObject();
-
- if( frag != nullptr ) {
- fragJSON.add( "pool", frag->pool->name );
- frag->write( &fragJSON );
+ if( frag == nullptr ) {
+ fragsJSON.add( JSON::OBJECT );
+ }
+ else {
+ fragsJSON.add( frag->write() );
}
}
- JSON& strFreedIndicesFreeingJSON = json->addArray( "strFreedIndicesFreeing" );
- foreach( i, strFreedIndices[freeing].citer() ) {
- strFreedIndicesFreeingJSON.add( *i );
- }
-
- JSON& objFreedIndicesFreeingJSON = json->addArray( "objFreedIndicesFreeing" );
- foreach( i, objFreedIndices[freeing].citer() ) {
- objFreedIndicesFreeingJSON.add( *i );
- }
-
- JSON& fragFreedIndicesFreeingJSON = json->addArray( "fragFreedIndicesFreeing" );
- foreach( i, fragFreedIndices[freeing].citer() ) {
- fragFreedIndicesFreeingJSON.add( *i );
- }
-
- JSON& strFreedIndicesWaitingJSON = json->addArray( "strFreedIndicesWaiting" );
- foreach( i, strFreedIndices[waiting].citer() ) {
- strFreedIndicesWaitingJSON.add( *i );
- }
-
- JSON& objFreedIndicesWaitingJSON = json->addArray( "objFreedIndicesWaiting" );
- foreach( i, objFreedIndices[waiting].citer() ) {
- objFreedIndicesWaitingJSON.add( *i );
- }
-
- JSON& fragFreedIndicesWaitingJSON = json->addArray( "fragFreedIndicesWaiting" );
- foreach( i, fragFreedIndices[waiting].citer() ) {
- fragFreedIndicesWaitingJSON.add( *i );
- }
-
- JSON& strAvailableIndicesJSON = json->addArray( "strAvailableIndices" );
- foreach( i, strAvailableIndices.citer() ) {
- strAvailableIndicesJSON.add( *i );
- }
-
- JSON& objAvailableIndicesJSON = json->addArray( "objAvailableIndices" );
- foreach( i, objAvailableIndices.citer() ) {
- objAvailableIndicesJSON.add( *i );
- }
-
- JSON& fragAvailableIndicesJSON = json->addArray( "fragAvailableIndices" );
- foreach( i, fragAvailableIndices.citer() ) {
- fragAvailableIndicesJSON.add( *i );
- }
+ return json;
}
void Orbis::load()
View
113 src/matrix/Orbis.hh
@@ -125,6 +125,54 @@ class Orbis : public Bounds
void reposition( Object* obj );
void reposition( Frag* frag );
+ /**
+ * Return structure at the given index, nullptr if index is -1.
+ */
+ OZ_ALWAYS_INLINE
+ Struct* str( int index ) const;
+
+ /**
+ * Return entity with the given index, nullptr if index is -1 or structure does not exist.
+ */
+ OZ_ALWAYS_INLINE
+ Entity* ent( int index ) const;
+
+ /**
+ * Return object at the given index, nullptr if index is -1.
+ */
+ OZ_ALWAYS_INLINE
+ Object* obj( int index ) const;
+
+ /**
+ * Return fragment at the given index, nullptr if index is -1.
+ */
+ OZ_ALWAYS_INLINE
+ Frag* frag( int index ) const;
+
+ /**
+ * Adjust structure index; return -1 if non-existent, original index otherwise.
+ */
+ OZ_ALWAYS_INLINE
+ int strIndex( int index ) const;
+
+ /**
+ * Adjust entity index; return -1 if structure does not exist, original index otherwise.
+ */
+ OZ_ALWAYS_INLINE
+ int entIndex( int index ) const;
+
+ /**
+ * Adjust object index; return -1 if non-existent, original index otherwise.
+ */
+ OZ_ALWAYS_INLINE
+ int objIndex( int index ) const;
+
+ /**
+ * Adjust fragment index; return -1 if non-existent, original index otherwise.
+ */
+ OZ_ALWAYS_INLINE
+ int fragIndex( int index ) const;
+
// get pointer to the cell the point is in
Cell* getCell( float x, float y );
Cell* getCell( const Point& p );
@@ -149,7 +197,7 @@ class Orbis : public Bounds
void write( OutputStream* ostream ) const;
void read( const JSON& json );
- void write( JSON* json ) const;
+ JSON write() const;
void load();
void unload();
@@ -162,6 +210,69 @@ class Orbis : public Bounds
extern Orbis orbis;
OZ_ALWAYS_INLINE
+inline Struct* Orbis::str( int index ) const
+{
+ return index == -1 ? nullptr : structs[index];
+}
+
+OZ_ALWAYS_INLINE
+inline Entity* Orbis::ent( int index ) const
+{
+ if( index == -1 ) {
+ return nullptr;
+ }
+
+ Struct* str = structs[index / Struct::MAX_ENTITIES];
+ if( str == nullptr ) {
+ return nullptr;
+ }
+ else {
+ return &str->entities[index % Struct::MAX_ENTITIES];
+ }
+}
+
+OZ_ALWAYS_INLINE
+inline Object* Orbis::obj( int index ) const
+{
+ return index == -1 ? nullptr : objects[index];
+}
+
+OZ_ALWAYS_INLINE
+inline Frag* Orbis::frag( int index ) const
+{
+ return index == -1 ? nullptr : frags[index];
+}
+
+OZ_ALWAYS_INLINE
+inline int Orbis::strIndex( int index ) const
+{
+ return index >= 0 && structs[index] == nullptr ? -1 : index;
+}
+
+OZ_ALWAYS_INLINE
+inline int Orbis::entIndex( int index ) const
+{
+ if( index == -1 ) {
+ return -1;
+ }
+
+ Struct* str = structs[index / Struct::MAX_ENTITIES];
+ return str == nullptr ? -1 : index;
+}
+
+OZ_ALWAYS_INLINE
+inline int Orbis::objIndex( int index ) const
+{
+ return index >= 0 && objects[index] == nullptr ? -1 : index;
+}
+
+OZ_ALWAYS_INLINE
+inline int Orbis::fragIndex( int index ) const
+{
+ return index >= 0 && frags[index] == nullptr ? -1 : index;
+}
+
+OZ_ALWAYS_INLINE
inline Cell* Orbis::getCell( float x, float y )
{
int ix = int( ( x + Orbis::DIM ) / Cell::SIZE );
View
37 src/matrix/Struct.cc
@@ -771,14 +771,15 @@ Struct::Struct( const BSP* bsp_, const JSON& json )
{
mins = json["mins"].asPoint();
maxs = json["maxs"].asPoint();
- transf = json["transf"].asMat44();
- invTransf = json["invTransf"].asMat44();
bsp = bsp_;
p = json["p"].asPoint();
heading = Heading( json["heading"].asInt() );
+ transf = Mat44::translation( p - Point::ORIGIN ) * ROTATIONS[heading];
+ invTransf = ROTATIONS[4 - heading] * Mat44::translation( Point::ORIGIN - p );
+
index = json["index"].asInt();
life = json["life"].asFloat();
@@ -827,7 +828,7 @@ Struct::Struct( const BSP* bsp_, const JSON& json )
}
}
-void Struct::write( OutputStream* ostream )
+void Struct::write( OutputStream* ostream ) const
{
ostream->writePoint( mins );
ostream->writePoint( maxs );
@@ -856,25 +857,27 @@ void Struct::write( OutputStream* ostream )
}
}
-void Struct::write( JSON* json )
+JSON Struct::write() const
{
- json->add( "mins", mins );
- json->add( "maxs", maxs );
- json->add( "transf", transf );
- json->add( "invTransf", invTransf );
+ JSON json( JSON::OBJECT );
- json->add( "p", p );
- json->add( "heading", heading );
+ json.add( "bsp", bsp->name );
- json->add( "index", index );
+ json.add( "mins", mins );
+ json.add( "maxs", maxs );
- json->add( "life", life );
- json->add( "demolishing", demolishing );
+ json.add( "p", p );
+ json.add( "heading", heading );
- JSON& entitiesJSON = json->addArray( "entities" );
+ json.add( "index", index );
+
+ json.add( "life", life );
+ json.add( "demolishing", demolishing );
+
+ JSON& entitiesJSON = json.add( "entities", JSON::ARRAY );
for( int i = 0; i < entities.length(); ++i ) {
- JSON& entityJSON = entitiesJSON.addObject();
+ JSON& entityJSON = entitiesJSON.add( JSON::OBJECT);
entityJSON.add( "offset", entities[i].offset );
entityJSON.add( "key", entities[i].key );
@@ -883,11 +886,13 @@ void Struct::write( JSON* json )
entityJSON.add( "time", entities[i].time );
}
- JSON& boundObjectsJSON = json->addArray( "boundObjects" );
+ JSON& boundObjectsJSON = json.add( "boundObjects", JSON::ARRAY );
for( int i = 0; i < boundObjects.length(); ++i ) {
boundObjectsJSON.add( boundObjects[i] );
}
+
+ return json;
}
}
View
4 src/matrix/Struct.hh
@@ -178,8 +178,8 @@ class Struct : public Bounds
explicit Struct( const BSP* bsp, InputStream* istream );
explicit Struct( const BSP* bsp, const JSON& json );
- void write( OutputStream* ostream );
- void write( JSON* json );
+ void write( OutputStream* ostream ) const;
+ JSON write() const;
OZ_STATIC_POOL_ALLOC( pool )
View
17 src/matrix/Terra.cc
@@ -120,5 +120,22 @@ void Terra::write( OutputStream* ostream ) const
ostream->writeString( name );
}
+void Terra::read( const JSON& json )
+{
+ const char* name = json["name"].get( "" );
+ int id = String::isEmpty( name ) ? -1 : liber.terraIndex( name );
+
+ load( id );
+}
+
+JSON Terra::write() const
+{
+ const char* name = id < 0 ? "" : liber.terrae[id].name.cstr();
+
+ JSON json( JSON::OBJECT );
+ json.add( "name", name );
+ return json;
+}
+
}
}
View
3 src/matrix/Terra.hh
@@ -81,6 +81,9 @@ class Terra
void read( InputStream* istream );
void write( OutputStream* ostream ) const;
+ void read( const JSON& json );
+ JSON write() const;
+
};
inline Span Terra::getInters( float minPosX, float minPosY,
View
34 src/matrix/Vehicle.cc
@@ -505,34 +505,36 @@ void Vehicle::write( OutputStream* ostream ) const
}
}
-void Vehicle::write( JSON* json ) const
+JSON Vehicle::write() const
{
- Dynamic::write( json );
+ JSON json = Dynamic::write();
- json->add( "h", h );
- json->add( "v", v );
- json->add( "w", w );
- json->add( "rotVelH", rotVelH );
- json->add( "rotVelV", rotVelV );
- json->add( "actions", actions );
- json->add( "oldActions", oldActions );
+ json.add( "h", h );
+ json.add( "v", v );
+ json.add( "w", w );
+ json.add( "rotVelH", rotVelH );
+ json.add( "rotVelV", rotVelV );
+ json.add( "actions", actions );
+ json.add( "oldActions", oldActions );
- json->add( "state", state );
- json->add( "oldState", oldState );
- json->add( "fuel", fuel );
+ json.add( "state", state );
+ json.add( "oldState", oldState );
+ json.add( "fuel", fuel );
- json->add( "pilot", pilot );
+ json.add( "pilot", orbis.objIndex( pilot ) );
- json->add( "weapon", weapon );
+ json.add( "weapon", orbis.objIndex( weapon ) );
- JSON& weaponsJSON = json->addArray();
+ JSON& weaponsJSON = json.add( JSON::ARRAY );
for( int i = 0; i < MAX_WEAPONS; ++i ) {
- JSON& weaponJSON = weaponsJSON.addObject();
+ JSON& weaponJSON = weaponsJSON.add( JSON::OBJECT );
weaponJSON.add( "nRounds", nRounds[i] );
weaponJSON.add( "shotTime", shotTime[i] );
}
+
+ return json;
}
void Vehicle::readUpdate( InputStream* )
View
2 src/matrix/Vehicle.hh
@@ -106,7 +106,7 @@ class Vehicle : public Dynamic
explicit Vehicle( const VehicleClass* clazz, const JSON& json );
void write( OutputStream* ostream ) const override;
- void write( JSON* json ) const override;
+ JSON write() const override;
void readUpdate( InputStream* istream ) override;
void writeUpdate( OutputStream* ostream ) const override;
View
10 src/matrix/Weapon.cc
@@ -129,12 +129,14 @@ void Weapon::write( OutputStream* ostream ) const
ostream->writeFloat( shotTime );
}
-void Weapon::write( JSON* json ) const
+JSON Weapon::write() const
{
- Dynamic::write( json );
+ JSON json = Dynamic::write();
- json->add( "nRounds", nRounds );
- json->add( "shotTime", shotTime );
+ json.add( "nRounds", nRounds );
+ json.add( "shotTime", shotTime );
+
+ return json;
}
void Weapon::readUpdate( InputStream* )
View
2 src/matrix/Weapon.hh
@@ -58,7 +58,7 @@ class Weapon : public Dynamic
explicit Weapon( const WeaponClass* clazz, const JSON& json );
void write( OutputStream* ostream ) const override;
- void write( JSON* json ) const override;
+ JSON write() const override;
void readUpdate( InputStream* istream ) override;
void writeUpdate( OutputStream* ostream ) const override;
View
1,112 src/ozCore/JSON.cc
@@ -731,10 +731,135 @@ JSON::JSON( Data* data_, Type valueType_ ) :
data( data_ ), valueType( valueType_ ), wasAccessed( false )
{}
-JSON::JSON() :
- data( nullptr ), valueType( NIL ), wasAccessed( true )
+JSON::JSON( Type type ) :
+ data( nullptr ), valueType( type ), wasAccessed( true )
+{
+ switch( type ) {
+ case NIL: {
+ break;
+ }
+ case BOOLEAN: {
+ data = new BooleanData( false );
+ break;
+ }
+ case NUMBER: {
+ data = new NumberData( 0.0 );
+ break;
+ }
+ case STRING: {
+ data = new StringData( "" );
+ break;
+ }
+ case ARRAY: {
+ data = new ArrayData();
+ break;
+ }
+ case OBJECT: {
+ data = new ObjectData();
+ break;
+ }
+ }
+}
+
+JSON::JSON( bool value ) :
+ data( new BooleanData( value ) ), valueType( BOOLEAN ), wasAccessed( true )
+{}
+
+JSON::JSON( int value ) :
+ data( new NumberData( value ) ), valueType( NUMBER ), wasAccessed( true )
+{}
+
+JSON::JSON( float value ) :
+ data( new NumberData( value ) ), valueType( NUMBER ), wasAccessed( true )
+{}
+
+JSON::JSON( double value ) :
+ data( new NumberData( value ) ), valueType( NUMBER ), wasAccessed( true )
+{}
+
+JSON::JSON( const String& value ) :
+ data( new StringData( value ) ), valueType( STRING ), wasAccessed( true )
+{}
+
+JSON::JSON( const char* value ) :
+ data( new StringData( value ) ), valueType( STRING ), wasAccessed( true )
{}
+JSON::JSON( const Vec3& v ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 3; ++i ) {
+ list.add( JSON( new NumberData( v[i] ), NUMBER ) );
+ }
+}
+
+JSON::JSON( const Vec4& v ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 4; ++i ) {
+ list.add( JSON( new NumberData( v[i] ), NUMBER ) );
+ }
+}
+
+JSON::JSON( const Point& p ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 3; ++i ) {
+ list.add( JSON( new NumberData( p[i] ), NUMBER ) );
+ }
+}
+
+JSON::JSON( const Plane& p ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 3; ++i ) {
+ list.add( JSON( new NumberData( p.n[i] ), NUMBER ) );
+ }
+ list.add( JSON( new NumberData( p.d ), NUMBER ) );
+}
+
+JSON::JSON( const Quat& q ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 3; ++i ) {
+ list.add( JSON( new NumberData( q[i] ), NUMBER ) );
+ }
+}
+
+JSON::JSON( const Mat33& m ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 3; ++i ) {
+ for( int j = 0; j < 3; ++j ) {
+ list.add( JSON( new NumberData( m[i][j] ), NUMBER ) );
+ }
+ }
+}
+
+JSON::JSON( const Mat44& m ) :
+ data( new ArrayData() ), valueType( ARRAY ), wasAccessed( true )
+{
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
+
+ for( int i = 0; i < 4; ++i ) {
+ for( int j = 0; j < 4; ++j ) {
+ list.add( JSON( new NumberData( m[i][j] ), NUMBER ) );
+ }
+ }
+}
+
JSON::JSON( const File& file ) :
data( nullptr ), valueType( NIL ), wasAccessed( true )
{
@@ -746,6 +871,36 @@ JSON::~JSON()
clear();
}
+JSON::JSON( const JSON& v ) :
+ data( nullptr ), valueType( v.valueType ), wasAccessed( v.wasAccessed )
+{
+ switch( valueType ) {
+ case NIL: {
+ break;
+ }
+ case BOOLEAN: {
+ data = new BooleanData( *static_cast<const BooleanData*>( v.data ) );
+ break;
+ }
+ case NUMBER: {
+ data = new NumberData( *static_cast<const NumberData*>( v.data ) );
+ break;
+ }
+ case STRING: {
+ data = new StringData( *static_cast<const StringData*>( v.data ) );
+ break;
+ }
+ case ARRAY: {
+ data = new ArrayData( *static_cast<const ArrayData*>( v.data ) );
+ break;
+ }
+ case OBJECT: {
+ data = new ObjectData( *static_cast<const ObjectData*>( v.data ) );
+ break;
+ }
+ }
+}
+
JSON::JSON( JSON&& v ) :
data( v.data ), valueType( v.valueType ), wasAccessed( v.wasAccessed )
{
@@ -754,8 +909,53 @@ JSON::JSON( JSON&& v ) :
v.wasAccessed = true;
}
+JSON& JSON::operator = ( const JSON& v )
+{
+ if( &v == this ) {
+ return *this;
+ }
+
+ clear();
+
+ valueType = v.valueType;
+ wasAccessed = v.wasAccessed;
+
+ switch( valueType ) {
+ case NIL: {
+ data = nullptr;
+ break;
+ }
+ case BOOLEAN: {
+ data = new BooleanData( *static_cast<const BooleanData*>( v.data ) );
+ break;
+ }
+ case NUMBER: {
+ data = new NumberData( *static_cast<const NumberData*>( v.data ) );
+ break;
+ }
+ case STRING: {
+ data = new StringData( *static_cast<const StringData*>( v.data ) );
+ break;
+ }
+ case ARRAY: {
+ data = new ArrayData( *static_cast<const ArrayData*>( v.data ) );
+ break;
+ }
+ case OBJECT: {
+ data = new ObjectData( *static_cast<const ObjectData*>( v.data ) );
+ break;
+ }
+ }
+
+ return *this;
+}
+
JSON& JSON::operator = ( JSON&& v )
{
+ if( &v == this ) {
+ return *this;
+ }
+
clear();
data = v.data;
@@ -924,22 +1124,22 @@ bool JSON::asBool() const
int JSON::asInt() const
{
- wasAccessed = true;
-
- if( valueType != NUMBER ) {
- OZ_ERROR( "JSON value accessed as an integer: %s", toString().cstr() );
- }
- return int( static_cast<const NumberData*>( data )->value );
+ return int( asDouble() );
}
float JSON::asFloat() const
{
+ return float( asDouble() );
+}
+
+double JSON::asDouble() const
+{
wasAccessed = true;
if( valueType != NUMBER ) {
- OZ_ERROR( "JSON value accessed as a float: %s", toString().cstr() );
+ OZ_ERROR( "JSON value accessed as a number: %s", toString().cstr() );
}
- return float( static_cast<const NumberData*>( data )->value );
+ return static_cast<const NumberData*>( data )->value;
}
const String& JSON::asString() const
@@ -1061,6 +1261,26 @@ void JSON::asArray( float* array, int count ) const
}
}
+void JSON::asArray( double* array, int count ) const
+{
+ wasAccessed = true;
+
+ if( valueType != ARRAY ) {
+ OZ_ERROR( "JSON value accessed as an array: %s", toString().cstr() );
+ }
+
+ const List<JSON>& list = static_cast<const ArrayData*>( data )->list;
+
+ if( list.length() != count ) {
+ OZ_ERROR( "JSON array has %d elements but %d expected: %s",
+ list.length(), count, toString().cstr() );
+ }
+
+ for( int i = 0; i < count; ++i ) {
+ array[i] = list[i].asDouble();
+ }
+}
+
void JSON::asArray( String* array, int count ) const
{
wasAccessed = true;
@@ -1243,7 +1463,7 @@ int JSON::get( int defaultValue ) const
return defaultValue;
}
else if( valueType != NUMBER ) {
- OZ_ERROR( "JSON value accessed as an integer: %s", toString().cstr() );
+ OZ_ERROR( "JSON value accessed as a number: %s", toString().cstr() );
}
return int( static_cast<const NumberData*>( data )->value );
@@ -1257,12 +1477,26 @@ float JSON::get( float defaultValue ) const
return defaultValue;
}
else if( valueType != NUMBER ) {
- OZ_ERROR( "JSON value accessed as a float: %s", toString().cstr() );
+ OZ_ERROR( "JSON value accessed as a number: %s", toString().cstr() );
}
return float( static_cast<const NumberData*>( data )->value );
}
+double JSON::get( double defaultValue ) const
+{
+ wasAccessed = true;
+
+ if( valueType == NIL ) {
+ return defaultValue;
+ }
+ else if( valueType != NUMBER ) {
+ OZ_ERROR( "JSON value accessed as a number: %s", toString().cstr() );
+ }
+
+ return static_cast<const NumberData*>( data )->value;
+}
+
const String& JSON::get( const String& defaultValue ) const
{
wasAccessed = true;
@@ -1405,6 +1639,30 @@ bool JSON::get( float* array, int count ) const
return true;
}
+bool JSON::get( double* array, int count ) const
+{
+ wasAccessed = true;
+
+ if( valueType == NIL ) {
+ return false;
+ }
+ else if( valueType != ARRAY ) {
+ OZ_ERROR( "JSON value accessed as an array: %s", toString().cstr() );
+ }
+
+ const List<JSON>& list = static_cast<const ArrayData*>( data )->list;
+
+ if( list.length() != count ) {
+ OZ_ERROR( "JSON array has %d elements but %d expected: %s",
+ list.length(), count, toString().cstr() );
+ }
+
+ for( int i = 0; i < count; ++i ) {
+ array[i] = list[i].asDouble();
+ }
+ return true;
+}
+
bool JSON::get( String* array, int count ) const
{
wasAccessed = true;
@@ -1597,823 +1855,53 @@ bool JSON::get( Mat44* array, int count ) const
return true;
}
-void JSON::setNull()
-{
- clear();
-}
-
-void JSON::set( bool value )
+JSON& JSON::add( const JSON& json )
{
- clear();
-
- data = new BooleanData( value );
- valueType = BOOLEAN;
-}
+ if( valueType != ARRAY ) {
+ OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
+ }
-void JSON::set( int value )
-{
- clear();
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
- data = new NumberData( value );
- valueType = NUMBER;
+ list.add( json );
+ return list.last();
}
-void JSON::set( float value )
+JSON& JSON::add( JSON&& json )
{
- clear();
-
- data = new NumberData( value );
- valueType = NUMBER;
-}
+ if( valueType != ARRAY ) {
+ OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
+ }
-void JSON::set( const String& value )
-{
- clear();
+ List<JSON>& list = static_cast<ArrayData*>( data )->list;
- data = new StringData( value );
- valueType = STRING;
+ list.add( json );
+ return list.last();
}
-void JSON::set( const char* value )
+JSON& JSON::add( const char* key, const JSON& json )
{
- clear();
+ if( valueType != OBJECT ) {
+ OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
+ key, toString().cstr() );
+ }
- data = new StringData( value );
- valueType = STRING;
+ HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
+ return table.add( key, json );
}
-void JSON::set( const Vec3& v )
+JSON& JSON::add( const char* key, JSON&& json )
{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- list.add( JSON( new NumberData( v[i] ), NUMBER ) );
- }
-}
-
-void JSON::set( const Vec4& v )
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- list.add( JSON( new NumberData( v[i] ), NUMBER ) );
- }
-}
-
-void JSON::set( const Point& p )
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- list.add( JSON( new NumberData( p[i] ), NUMBER ) );
- }
-}
-
-void JSON::set( const Plane& p )
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- list.add( JSON( new NumberData( p.n[i] ), NUMBER ) );
- }
- list.add( JSON( new NumberData( p.d ), NUMBER ) );
-}
-
-void JSON::set( const Quat& q )
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- list.add( JSON( new NumberData( q[i] ), NUMBER ) );
- }
-}
-
-void JSON::set( const Mat33& m )
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- for( int j = 0; j < 3; ++j ) {
- list.add( JSON( new NumberData( m[i][j] ), NUMBER ) );
- }
- }
-}
-
-void JSON::set( const Mat44& m )
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- for( int j = 0; j < 4; ++j ) {
- list.add( JSON( new NumberData( m[i][j] ), NUMBER ) );
- }
- }
-}
-
-void JSON::setArray()
-{
- clear();
-
- data = new ArrayData();
- valueType = ARRAY;
-}
-
-void JSON::setObject()
-{
- clear();
-
- data = new ObjectData();
- valueType = OBJECT;
-}
-
-JSON& JSON::addNull()
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
-
- list.add( JSON( nullptr, NIL ) );
- return list.last();
-}
-
-JSON& JSON::add( bool value )
-{
- JSON& elem = addNull();
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( int value )
-{
- JSON& elem = addNull();
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( float value )
-{
- JSON& elem = addNull();
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const String& value )
-{
- JSON& elem = addNull();
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const char* value )
-{
- JSON& elem = addNull();
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const Vec3& v )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- elemList.add( JSON( new NumberData( v[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const Vec4& v )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- elemList.add( JSON( new NumberData( v[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const Point& p )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- elemList.add( JSON( new NumberData( p[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const Plane& p )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- elemList.add( JSON( new NumberData( p.n[i] ), NUMBER ) );
- }
- elemList.add( JSON( new NumberData( p.d ), NUMBER ) );
- return elem;
-}
-
-JSON& JSON::add( const Quat& q )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- elemList.add( JSON( new NumberData( q[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const Mat33& m )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- for( int j = 0; j < 3; ++j ) {
- elemList.add( JSON( new NumberData( m[i][j] ), NUMBER ) );
- }
- }
- return elem;
-}
-
-JSON& JSON::add( const Mat44& m )
-{
- if( valueType != ARRAY ) {
- OZ_ERROR( "Tried to add a value to a non-array JSON value: %s", toString().cstr() );
- }
-
- List<JSON>& list = static_cast<ArrayData*>( data )->list;
- list.add( JSON( new ArrayData(), ARRAY ) );
-
- JSON& elem = list.last();
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- for( int j = 0; j < 4; ++j ) {
- elemList.add( JSON( new NumberData( m[i][j] ), NUMBER ) );
- }
- }
- return elem;
-}
-
-JSON& JSON::addArray()
-{
- JSON& elem = addNull();
-
- elem.setArray();
- return elem;
-}
-
-JSON& JSON::addObject()
-{
- JSON& elem = addNull();
-
- elem.setObject();
- return elem;
-}
-
-JSON& JSON::addNull( const char* key )
-{
- if( valueType != OBJECT ) {
- OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
- key, toString().cstr() );
- }
-
- HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
- return table.add( key, JSON( nullptr, NIL ) );
-}
-
-JSON& JSON::add( const char* key, bool value )
-{
- JSON& elem = addNull( key );
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const char* key, int value )
-{
- JSON& elem = addNull( key );
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const char* key, float value )
-{
- JSON& elem = addNull( key );
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const char* key, const String& value )
-{
- JSON& elem = addNull( key );
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const char* key, const char* value )
-{
- JSON& elem = addNull( key );
-
- elem.set( value );
- return elem;
-}
-
-JSON& JSON::add( const char* key, const Vec3& v )
-{
- if( valueType != OBJECT ) {
- OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
- key, toString().cstr() );
- }
-
- HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
- JSON& elem = table.add( key, JSON( new ArrayData(), ARRAY ) );
-
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- elemList.add( JSON( new NumberData( v[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const char* key, const Vec4& v )
-{
- if( valueType != OBJECT ) {
- OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
- key, toString().cstr() );
- }
-
- HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
- JSON& elem = table.add( key, JSON( new ArrayData(), ARRAY ) );
-
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- elemList.add( JSON( new NumberData( v[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const char* key, const Point& p )
-{
- if( valueType != OBJECT ) {
- OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
- key, toString().cstr() );
- }
-
- HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
- JSON& elem = table.add( key, JSON( new ArrayData(), ARRAY ) );
-
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- elemList.add( JSON( new NumberData( p[i] ), NUMBER ) );
- }
- return elem;
-}
-
-JSON& JSON::add( const char* key, const Plane& p )
-{
- if( valueType != OBJECT ) {
- OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
- key, toString().cstr() );
- }
-
- HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
- JSON& elem = table.add( key, JSON( new ArrayData(), ARRAY ) );
-
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 3; ++i ) {
- elemList.add( JSON( new NumberData( p.n[i] ), NUMBER ) );
- }
- elemList.add( JSON( new NumberData( p.d ), NUMBER ) );
- return elem;
-}
-
-JSON& JSON::add( const char* key, const Quat& q )
-{
- if( valueType != OBJECT ) {
- OZ_ERROR( "Tried to add a key-value pair '%s' to a non-object JSON value: %s",
- key, toString().cstr() );
- }
-
- HashMap<String, JSON>& table = static_cast<ObjectData*>( data )->table;
- JSON& elem = table.add( key, JSON( new ArrayData(), ARRAY ) );
-
- List<JSON>& elemList = static_cast<ArrayData*>( elem.data )->list;
-
- for( int i = 0; i < 4; ++i ) {
- elemList.add( JSON(