Skip to content

Commit

Permalink
Merge pull request #37640 from BevapDin/faw
Browse files Browse the repository at this point in the history
Make mapgen loading code a bit simpler:
  • Loading branch information
ZhilkinSerg authored Feb 2, 2020
2 parents 9ddf00b + 0659885 commit 5f3e918
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 50 deletions.
9 changes: 0 additions & 9 deletions src/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,6 @@ bool JsonObject::has_member( const std::string &name ) const
return positions.count( name ) > 0;
}

std::set<std::string> JsonObject::get_member_names() const
{
std::set<std::string> ret;
for( auto &elem : positions ) {
ret.insert( elem.first );
}
return ret;
}

std::string JsonObject::line_number() const
{
jsin->seek( start );
Expand Down
1 change: 0 additions & 1 deletion src/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,6 @@ class JsonObject

void allow_omitted_members() const;
bool has_member( const std::string &name ) const; // true iff named member exists
std::set<std::string> get_member_names() const;
std::string str() const; // copy object json as string
[[noreturn]] void throw_error( std::string err ) const;
[[noreturn]] void throw_error( std::string err, const std::string &name ) const;
Expand Down
78 changes: 38 additions & 40 deletions src/mapgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1826,13 +1826,12 @@ an overload below.
The mapgen piece is loaded from the member of the json object named key.
*/
template<typename PieceType>
void load_place_mapings( const JsonObject &pjo, const std::string &key,
mapgen_palette::placing_map::mapped_type &vect )
void load_place_mapings( const JsonValue &value, mapgen_palette::placing_map::mapped_type &vect )
{
if( pjo.has_object( key ) ) {
load_place_mapings<PieceType>( pjo.get_object( key ), vect );
if( value.test_object() ) {
load_place_mapings<PieceType>( value.get_object(), vect );
} else {
for( JsonObject jo : pjo.get_array( key ) ) {
for( JsonObject jo : value.get_array() ) {
load_place_mapings<PieceType>( jo, vect );
jo.allow_omitted_members();
}
Expand All @@ -1841,23 +1840,22 @@ void load_place_mapings( const JsonObject &pjo, const std::string &key,

/*
This function allows loading the mapgen pieces from a single string, *or* a json object.
The mapgen piece is loaded from the member of the json object named key.
*/
template<typename PieceType>
void load_place_mapings_string( const JsonObject &pjo, const std::string &key,
void load_place_mapings_string( const JsonValue &value,
mapgen_palette::placing_map::mapped_type &vect )
{
if( pjo.has_string( key ) ) {
if( value.test_string() ) {
try {
vect.push_back( make_shared_fast<PieceType>( pjo.get_string( key ) ) );
vect.push_back( make_shared_fast<PieceType>( value.get_string() ) );
} catch( const std::runtime_error &err ) {
// Using the json object here adds nice formatting and context information
pjo.throw_error( err.what(), key );
value.throw_error( err.what() );
}
} else if( pjo.has_object( key ) ) {
load_place_mapings<PieceType>( pjo.get_object( key ), vect );
} else if( value.test_object() ) {
load_place_mapings<PieceType>( value.get_object(), vect );
} else {
for( const JsonValue entry : pjo.get_array( key ) ) {
for( const JsonValue entry : value.get_array() ) {
if( entry.test_string() ) {
try {
vect.push_back( make_shared_fast<PieceType>( entry.get_string() ) );
Expand All @@ -1877,14 +1875,14 @@ instance of jmapgen_alternativly which will chose the mapgen piece to apply to t
Use this with terrain or traps or other things that can not be applied twice to the same place.
*/
template<typename PieceType>
void load_place_mapings_alternatively( const JsonObject &pjo, const std::string &key,
void load_place_mapings_alternatively( const JsonValue &value,
mapgen_palette::placing_map::mapped_type &vect )
{
if( !pjo.has_array( key ) ) {
load_place_mapings_string<PieceType>( pjo, key, vect );
if( !value.test_array() ) {
load_place_mapings_string<PieceType>( value, vect );
} else {
auto alter = make_shared_fast< jmapgen_alternativly<PieceType> >();
for( const JsonValue entry : pjo.get_array( key ) ) {
for( const JsonValue entry : value.get_array() ) {
if( entry.test_string() ) {
try {
alter->alternatives.emplace_back( entry.get_string() );
Expand Down Expand Up @@ -1933,24 +1931,24 @@ void load_place_mapings_alternatively( const JsonObject &pjo, const std::string
}

template<>
void load_place_mapings<jmapgen_trap>( const JsonObject &pjo, const std::string &key,
void load_place_mapings<jmapgen_trap>( const JsonValue &value,
mapgen_palette::placing_map::mapped_type &vect )
{
load_place_mapings_alternatively<jmapgen_trap>( pjo, key, vect );
load_place_mapings_alternatively<jmapgen_trap>( value, vect );
}

template<>
void load_place_mapings<jmapgen_furniture>( const JsonObject &pjo, const std::string &key,
void load_place_mapings<jmapgen_furniture>( const JsonValue &value,
mapgen_palette::placing_map::mapped_type &vect )
{
load_place_mapings_alternatively<jmapgen_furniture>( pjo, key, vect );
load_place_mapings_alternatively<jmapgen_furniture>( value, vect );
}

template<>
void load_place_mapings<jmapgen_terrain>( const JsonObject &pjo, const std::string &key,
void load_place_mapings<jmapgen_terrain>( const JsonValue &value,
mapgen_palette::placing_map::mapped_type &vect )
{
load_place_mapings_alternatively<jmapgen_terrain>( pjo, key, vect );
load_place_mapings_alternatively<jmapgen_terrain>( value, vect );
}

template<typename PieceType>
Expand All @@ -1969,7 +1967,7 @@ void mapgen_palette::load_place_mapings( const JsonObject &jo, const std::string
continue;
}
auto &vect = format_placings[ key[0] ];
::load_place_mapings<PieceType>( sub, member_name, vect );
::load_place_mapings<PieceType>( sub.get_member( member_name ), vect );
}
}
if( !jo.has_object( member_name ) ) {
Expand All @@ -1981,13 +1979,13 @@ void mapgen_palette::load_place_mapings( const JsonObject &jo, const std::string
if( member_name == "terrain" || member_name == "furniture" ) {
return;
}
JsonObject pjo = jo.get_object( member_name );
for( auto &key : pjo.get_member_names() ) {
for( const JsonMember member : jo.get_object( member_name ) ) {
const std::string &key = member.name();
if( key.size() != 1 ) {
pjo.throw_error( "format map key must be 1 character", key );
member.throw_error( "format map key must be 1 character" );
}
auto &vect = format_placings[ key[0] ];
::load_place_mapings<PieceType>( pjo, key, vect );
::load_place_mapings<PieceType>( member, vect );
}
}

Expand Down Expand Up @@ -2063,16 +2061,16 @@ mapgen_palette mapgen_palette::load_internal( const JsonObject &jo, const std::s
// mandatory: every character in rows must have matching entry, unless fill_ter is set
// "terrain": { "a": "t_grass", "b": "t_lava" }
if( jo.has_member( "terrain" ) ) {
JsonObject pjo = jo.get_object( "terrain" );
for( const auto &key : pjo.get_member_names() ) {
for( const JsonMember member : jo.get_object( "terrain" ) ) {
const std::string &key = member.name();
if( key.size() != 1 ) {
pjo.throw_error( "format map key must be 1 character", key );
member.throw_error( "format map key must be 1 character" );
}
if( pjo.has_string( key ) ) {
format_terrain[key[0]] = ter_id( pjo.get_string( key ) );
if( member.test_string() ) {
format_terrain[key[0]] = ter_id( member.get_string() );
} else {
auto &vect = format_placings[ key[0] ];
::load_place_mapings<jmapgen_terrain>( pjo, key, vect );
::load_place_mapings<jmapgen_terrain>( member, vect );
if( !vect.empty() ) {
// Dummy entry to signal that this terrain is actually defined, because
// the code below checks that each square on the map has a valid terrain
Expand All @@ -2084,16 +2082,16 @@ mapgen_palette mapgen_palette::load_internal( const JsonObject &jo, const std::s
}

if( jo.has_object( "furniture" ) ) {
JsonObject pjo = jo.get_object( "furniture" );
for( const auto &key : pjo.get_member_names() ) {
for( const JsonMember member : jo.get_object( "furniture" ) ) {
const std::string &key = member.name();
if( key.size() != 1 ) {
pjo.throw_error( "format map key must be 1 character", key );
member.throw_error( "format map key must be 1 character" );
}
if( pjo.has_string( key ) ) {
format_furniture[key[0]] = furn_id( pjo.get_string( key ) );
if( member.test_string() ) {
format_furniture[key[0]] = furn_id( member.get_string() );
} else {
auto &vect = format_placings[ key[0] ];
::load_place_mapings<jmapgen_furniture>( pjo, key, vect );
::load_place_mapings<jmapgen_furniture>( member, vect );
}
}
}
Expand Down

0 comments on commit 5f3e918

Please sign in to comment.