182 lines
4.3 KiB
C++
182 lines
4.3 KiB
C++
/* Copyright 2016-2017 Joaquin M Lopez Munoz.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
|
* http://www.boost.org/LICENSE_1_0.txt)
|
|
*
|
|
* See http://www.boost.org/libs/poly_collection for library home page.
|
|
*/
|
|
|
|
/* segment-specific operations */
|
|
|
|
#include <algorithm>
|
|
#include <boost/poly_collection/any_collection.hpp>
|
|
#include <boost/poly_collection/base_collection.hpp>
|
|
#include <boost/type_erasure/operators.hpp>
|
|
#include <memory>
|
|
#include <random>
|
|
#include "rolegame.hpp"
|
|
|
|
std::ostream& operator<<(std::ostream& os,const sprite& s)
|
|
{
|
|
s.render(os);
|
|
return os;
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& os,const window& w)
|
|
{
|
|
w.display(os);
|
|
return os;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
boost::base_collection<sprite> c;
|
|
|
|
//[segmented_structure_1
|
|
//= std::unique_ptr<sprite> make_sprite()
|
|
//= {
|
|
//<-
|
|
auto make_sprite=[]()->std::unique_ptr<sprite>{
|
|
//->
|
|
static std::mt19937 gen{92748};
|
|
static std::discrete_distribution<> rnd{{1,1,1}};
|
|
static int id=0;
|
|
|
|
switch(rnd(gen)){
|
|
//<-
|
|
default:
|
|
//->
|
|
case 0: return std::make_unique<warrior>(id++);break;
|
|
case 1: return std::make_unique<juggernaut>(id++);break;
|
|
case 2: return std::make_unique<goblin>(id++);break;
|
|
}
|
|
//<-
|
|
};
|
|
//->
|
|
//= }
|
|
//= ...
|
|
//=
|
|
//<-
|
|
try{
|
|
//->
|
|
for(int i=0;i<8;++i)c.insert(*make_sprite());
|
|
// throws boost::poly_collection::unregistered_type
|
|
//<-
|
|
}catch(boost::poly_collection::unregistered_type&){}
|
|
//->
|
|
//]
|
|
|
|
//[segmented_structure_2
|
|
std::cout<<c.is_registered<warrior>()<<"\n"; // prints 0
|
|
std::cout<<c.is_registered(typeid(warrior))<<"\n"; // alternate syntax
|
|
//]
|
|
|
|
//[segmented_structure_3
|
|
c.register_types<warrior,juggernaut,goblin>();
|
|
// everything works fine now
|
|
for(int i=0;i<8;++i)c.insert(*make_sprite());
|
|
//]
|
|
|
|
using renderable=boost::type_erasure::ostreamable<>;
|
|
//[segmented_structure_4
|
|
boost::any_collection<renderable> c1,c2;
|
|
//= ... // populate c2
|
|
//=
|
|
//<-
|
|
c2.insert(window{"pop-up"});
|
|
try{
|
|
//->
|
|
c1.insert(*c2.begin()); // throws: actual type of *c2.begin() not known by c1
|
|
//<-
|
|
}catch(boost::poly_collection::unregistered_type&){}
|
|
//->
|
|
//]
|
|
|
|
//[segmented_structure_5
|
|
//= ... // populate c with 8 assorted entities
|
|
//=
|
|
std::cout<<c.size()<<"\n"; // 8 sprites
|
|
std::cout<<c.size<juggernaut>()<<"\n"; // 2 juggernauts
|
|
std::cout<<c.size(typeid(juggernaut))<<"\n"; // alternate syntax
|
|
c.clear<juggernaut>(); // remove juggenauts only
|
|
std::cout<<c.empty<juggernaut>()<<"\n"; // 1 (no juggernauts left)
|
|
std::cout<<c.size()<<"\n"; // 6 sprites remaining
|
|
//]
|
|
|
|
//[segmented_structure_6
|
|
const char* comma="";
|
|
for(auto first=c.begin(typeid(warrior)),last=c.end(typeid(warrior));
|
|
first!=last;++first){
|
|
std::cout<<comma;
|
|
first->render(std::cout);
|
|
comma=",";
|
|
}
|
|
std::cout<<"\n";
|
|
//]
|
|
|
|
//[segmented_structure_7
|
|
/*=const char**/ comma="";
|
|
for(const auto& x:c.segment(typeid(warrior))){
|
|
std::cout<<comma;
|
|
x.render(std::cout);
|
|
comma=",";
|
|
}
|
|
std::cout<<"\n";
|
|
//]
|
|
|
|
//[segmented_structure_8
|
|
/*=const char**/ comma="";
|
|
for(auto first=c.begin<warrior>(),last=c.end<warrior>();
|
|
first!=last;++first){
|
|
first->rank.insert(0,"super");
|
|
std::cout<<comma;
|
|
first->render(std::cout);
|
|
comma=",";
|
|
}
|
|
std::cout<<"\n";
|
|
|
|
// range-based for loop alternative
|
|
|
|
/*=const char**/ comma="";
|
|
for(auto& x:c.segment<warrior>()){
|
|
x.rank.insert(0,"super");
|
|
//<-
|
|
auto it=x.rank.begin();
|
|
x.rank.erase(it,it+5); // undo previos op, 5==len("super");
|
|
//->
|
|
std::cout<<comma;
|
|
x.render(std::cout);
|
|
comma=",";
|
|
}
|
|
std::cout<<"\n";
|
|
|
|
//]
|
|
|
|
auto render=[&](){
|
|
//[segmented_structure_9
|
|
const char* comma="";
|
|
for(auto seg:c.segment_traversal()){
|
|
for(sprite& s:seg){
|
|
std::cout<<comma;
|
|
s.render(std::cout);
|
|
comma=",";
|
|
}
|
|
}
|
|
std::cout<<"\n";
|
|
//]
|
|
};
|
|
render();
|
|
|
|
//[segmented_structure_10
|
|
c.reserve<goblin>(100); // no reallocation till we exceed 100 goblins
|
|
std::cout<<c.capacity<goblin>()<<"\n"; // prints 100
|
|
//]
|
|
|
|
//[segmented_structure_11
|
|
c.reserve(1000); // reserve(1000) for each segment
|
|
std::cout<<c.capacity<warrior>()<<", "
|
|
<<c.capacity<juggernaut>()<<", "
|
|
<<c.capacity<goblin>()<<"\n"; // prints 1000, 1000, 1000
|
|
//]
|
|
}
|