Refactored ItemManager to use static components to load

the default item meshes. An instance of it is now only
created when a race is started (and deleted once the
race is finished). This makes the race-specific 
initialisation and cleanup better to understand. Also
added singleton access to the one instance of ItemManager.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11498 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-08-09 06:37:29 +00:00
parent 98c5a5aba9
commit e2caea1c05
12 changed files with 149 additions and 131 deletions

View File

@ -26,7 +26,6 @@
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "items/item.hpp"
#include "items/item_manager.hpp"
#include "karts/kart_properties.hpp"
STKConfig* stk_config=0;

View File

@ -580,7 +580,7 @@ void IrrDriver::applyResolutionSettings()
attachment_manager -> removeTextures();
projectile_manager -> removeTextures();
item_manager -> removeTextures();
ItemManager::removeTextures();
kart_properties_manager -> unloadAllKarts();
powerup_manager -> unloadPowerups();
Referee::cleanup();
@ -626,7 +626,7 @@ void IrrDriver::applyResolutionSettings()
}
powerup_manager -> loadAllPowerups ();
item_manager -> loadDefaultItems();
ItemManager::loadDefaultItemMeshes();
projectile_manager -> loadData();
Referee::init();
GUIEngine::addLoadingIcon(

View File

@ -39,69 +39,31 @@
ItemManager* item_manager;
//-----------------------------------------------------------------------------
typedef std::map<std::string,scene::IMesh*>::const_iterator CI_type;
std::vector<scene::IMesh *> ItemManager::m_item_mesh;
std::vector<scene::IMesh *> ItemManager::m_item_lowres_mesh;
ItemManager * ItemManager::m_item_manager = NULL;
ItemManager::ItemManager()
//-----------------------------------------------------------------------------
/** Creates one instance of the item manager. */
void ItemManager::create()
{
m_switch_time = -1.0f;
// The actual loading is done in loadDefaultItems
// Prepare the switch to array, which stores which item should be
// switched to what other item. Initialise it with a mapping that
// each item is switched to itself, so basically a no-op.
m_switch_to.reserve(Item::ITEM_COUNT);
for(unsigned int i=Item::ITEM_FIRST; i<Item::ITEM_COUNT; i++)
m_switch_to.push_back((Item::ItemType)i);
setSwitchItems(stk_config->m_switch_items);
} // ItemManager
assert(!m_item_manager);
m_item_manager = new ItemManager();
} // create
//-----------------------------------------------------------------------------
/** Sets which objects is getting switched to what.
* \param switch A mapping of items types to item types for the mapping.
* must contain one entry for each item.
*/
void ItemManager::setSwitchItems(const std::vector<int> &switch_items)
/** Destroys the one instance of the item manager. */
void ItemManager::destroy()
{
for(unsigned int i=Item::ITEM_FIRST; i<Item::ITEM_COUNT; i++)
m_switch_to[i]=(Item::ItemType)stk_config->m_switch_items[i];
} // setSwitchItems
//-----------------------------------------------------------------------------
/** Clean up all textures. This is necessary when switching resolution etc.
*/
void ItemManager::removeTextures()
{
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
delete *i;
}
m_all_items.clear();
for(unsigned int i=0; i<Item::ITEM_LAST-Item::ITEM_FIRST+1; i++)
{
if(m_item_mesh[i] ) m_item_mesh[i]->drop();
if(m_item_lowres_mesh[i]) m_item_lowres_mesh[i]->drop();
}
} // removeTextures
//-----------------------------------------------------------------------------
/** Destructor. Cleans up all items and meshes stored.
*/
ItemManager::~ItemManager()
{
for(unsigned int i=0; i<Item::ITEM_LAST-Item::ITEM_FIRST+1; i++)
{
if(m_item_mesh[i] ) m_item_mesh[i]->drop();
if(m_item_lowres_mesh[i]) m_item_lowres_mesh[i]->drop();
}
} // ~ItemManager
assert(m_item_manager);
delete m_item_manager;
m_item_manager = NULL;
} // destroy
//-----------------------------------------------------------------------------
/** Loads the default item meshes (high- and low-resolution).
*/
void ItemManager::loadDefaultItems()
void ItemManager::loadDefaultItemMeshes()
{
m_item_mesh.resize(Item::ITEM_LAST-Item::ITEM_FIRST+1, NULL);
m_item_lowres_mesh.resize(Item::ITEM_LAST-Item::ITEM_FIRST+1, NULL);
@ -145,7 +107,65 @@ void ItemManager::loadDefaultItems()
if (m_item_lowres_mesh[i]) m_item_lowres_mesh[i]->grab();
} // for i
delete root;
} // loadDefaultItems
} // loadDefaultItemMeshes
//-----------------------------------------------------------------------------
/** Clean up all textures. This is necessary when switching resolution etc.
*/
void ItemManager::removeTextures()
{
for(unsigned int i=0; i<Item::ITEM_LAST-Item::ITEM_FIRST+1; i++)
{
if(m_item_mesh[i] ) m_item_mesh[i]->drop();
m_item_mesh[i] = NULL;
if(m_item_lowres_mesh[i]) m_item_lowres_mesh[i]->drop();
m_item_lowres_mesh[i] = NULL;
}
} // removeTextures
// ============================================================================
/** Creates a new instance of the item manager. This is done at startup
* of each race. */
ItemManager::ItemManager()
{
m_switch_time = -1.0f;
// The actual loading is done in loadDefaultItems
// Prepare the switch to array, which stores which item should be
// switched to what other item. Initialise it with a mapping that
// each item is switched to itself, so basically a no-op.
m_switch_to.reserve(Item::ITEM_COUNT);
for(unsigned int i=Item::ITEM_FIRST; i<Item::ITEM_COUNT; i++)
m_switch_to.push_back((Item::ItemType)i);
setSwitchItems(stk_config->m_switch_items);
} // ItemManager
//-----------------------------------------------------------------------------
/** Sets which objects is getting switched to what.
* \param switch A mapping of items types to item types for the mapping.
* must contain one entry for each item.
*/
void ItemManager::setSwitchItems(const std::vector<int> &switch_items)
{
for(unsigned int i=Item::ITEM_FIRST; i<Item::ITEM_COUNT; i++)
m_switch_to[i]=(Item::ItemType)stk_config->m_switch_items[i];
} // setSwitchItems
//-----------------------------------------------------------------------------
/** Destructor. Cleans up all items and meshes stored.
*/
ItemManager::~ItemManager()
{
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
if(*i)
delete *i;
}
m_all_items.clear();
} // ~ItemManager
//-----------------------------------------------------------------------------
/** Inserts the new item into the items management data structures, if possible
@ -247,24 +267,9 @@ void ItemManager::checkItemHit(AbstractKart* kart)
} // for m_all_items
} // checkItemHit
//-----------------------------------------------------------------------------
/** Remove all item instances, and the track specific models. This is used
* just before a new track is loaded and a race is started.
*/
void ItemManager::cleanup()
{
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
if(*i)
delete *i;
}
m_all_items.clear();
} // cleanup
//-----------------------------------------------------------------------------
/** Resets all items and removes bubble gum that is stuck on the track.
* This is done when a race is restarted.
* This is done when a race is (re)started.
*/
void ItemManager::reset()
{

View File

@ -20,6 +20,7 @@
#define HEADER_ITEMMANAGER_HPP
#include <assert.h>
#include <map>
#include <string>
#include <vector>
@ -34,21 +35,35 @@ class Kart;
*/
class ItemManager : public NoCopy
{
// Some static data and functions to initialise it:
private:
/** Stores all item models. */
static std::vector<scene::IMesh *> m_item_mesh;
/** Stores all low-resolution item models. */
static std::vector<scene::IMesh *> m_item_lowres_mesh;
/** The instance of ItemManager while a race is on. */
static ItemManager *m_item_manager;
public:
static void loadDefaultItemMeshes();
static void removeTextures();
static void create();
static void destroy();
/** Return an instance of the item manager (it does not automatically
* create one, call create for that). */
static ItemManager *get() {
assert(m_item_manager);
return m_item_manager;
} // get
// ========================================================================
private:
/** The vector of all items of the current track. */
typedef std::vector<Item*> AllItemTypes;
AllItemTypes m_all_items;
/** This stores all item models. */
std::vector<scene::IMesh *> m_item_mesh;
std::vector<scene::IMesh *> m_item_lowres_mesh;
/** The filename of item.xml, which can be overwritten from the command line
* in order to select different models. */
std::string m_user_filename;
/** What item this item is switched to. */
std::vector<Item::ItemType> m_switch_to;
@ -58,10 +73,12 @@ private:
void insertItem(Item *item);
public:
// Make those private so only create/destroy functions can call them.
ItemManager();
~ItemManager();
void loadDefaultItems();
void setSwitchItems(const std::vector<int> &switch_items);
public:
Item* newItem (Item::ItemType type, const Vec3& xyz,
const Vec3 &normal,
AbstractKart* parent=NULL);
@ -69,14 +86,10 @@ public:
TriggerItemListener* listener);
void update (float delta);
void checkItemHit (AbstractKart* kart);
void cleanup ();
void reset ();
void removeTextures ();
void setUserFilename (char *s) {m_user_filename=s;}
void collectedItem (int item_id, AbstractKart *kart,
int add_info=-1);
void switchItems ();
void setSwitchItems(const std::vector<int> &switch_items);
// ------------------------------------------------------------------------
scene::IMesh* getItemModel (Item::ItemType type)
{return m_item_mesh[type];}
@ -88,6 +101,4 @@ public:
const Item * getItem(unsigned int n) const { return m_all_items[n]; };
}; // ItemManager
extern ItemManager* item_manager;
#endif

View File

@ -221,13 +221,13 @@ void Powerup::use()
break ;
case PowerupManager::POWERUP_SWITCH:
{
item_manager->switchItems();
m_sound_use->position(m_owner->getXYZ());
m_sound_use->play();
ItemManager::get()->switchItems();
m_sound_use->position(m_owner->getXYZ());
m_sound_use->play();
gui->addMessage(getSwapperString(), NULL, 3.0f,
video::SColor(255, 255, 255, 255), false);
break;
gui->addMessage(getSwapperString(), NULL, 3.0f,
video::SColor(255, 255, 255, 255), false);
break;
}
case PowerupManager::POWERUP_CAKE:
case PowerupManager::POWERUP_RUBBERBALL:
@ -300,7 +300,7 @@ void Powerup::use()
pos.setY(hit_point.getY()-0.05f);
item_manager->newItem(Item::ITEM_BUBBLEGUM, pos, normal, m_owner);
ItemManager::get()->newItem(Item::ITEM_BUBBLEGUM, pos, normal, m_owner);
}
break;

View File

@ -446,9 +446,9 @@ void PresentAI::handleSteering(float dt)
Vec3 minpos = straight_point;
float mindist = -1000;
int mintype=-100;
for (unsigned int i = 0; i < item_manager->getNumberOfItems(); i++)
for (unsigned int i=0; i < ItemManager::get()->getNumberOfItems(); i++)
{
const Item *item = item_manager->getItem(i);
const Item *item = ItemManager::get()->getItem(i);
if (item && !item->wasCollected() &&
(item->getType() == Item::ITEM_BONUS_BOX ||
item->getType() == Item::ITEM_NITRO_BIG ||
@ -465,7 +465,7 @@ void PresentAI::handleSteering(float dt)
mintype = item->getType();
} // if dist < mindist || mindist<-100
} // if item && ...
} // for i <item_manager->getNumberOfItems()
} // for i <ItemManager::get()->getNumberOfItems()
float w = QuadGraph::get()->getNode(m_track_node).getPathWidth();
w *= w;
if ((btAngle(straight_point - me, minpos - me) < M_PI / 8 && mindist < w * 8) ||

View File

@ -1145,7 +1145,7 @@ void Kart::update(float dt)
} // if there is material
// Check if any item was hit.
item_manager->checkItemHit(this);
ItemManager::get()->checkItemHit(this);
static video::SColor pink(255, 255, 133, 253);

View File

@ -369,7 +369,6 @@ void cmdLineHelp (char* invocation)
" --reverse Play track in reverse (if allowed)\n"
// TODO: add back "--players" switch
// " --players n Define number of players to between 1 and 4.\n"
" --item STYLE Use STYLE as your item style.\n"
" -f, --fullscreen Select fullscreen display.\n"
" -w, --windowed Windowed display (default).\n"
" -s, --screensize WxH Set the screen size (e.g. 320x200).\n"
@ -999,11 +998,6 @@ int handleCmdLine(int argc, char **argv)
','));
i++;
}
else if( !strcmp(argv[i], "--item") && i+1<argc )
{
item_manager->setUserFilename(argv[i+1]);
i++;
}
// these commands are already processed in handleCmdLinePreliminary,
// but repeat this just so that we don't get error messages about
// unknown commands
@ -1127,7 +1121,6 @@ void initRest()
kart_properties_manager = new KartPropertiesManager();
projectile_manager = new ProjectileManager ();
powerup_manager = new PowerupManager ();
item_manager = new ItemManager ();
attachment_manager = new AttachmentManager ();
highscore_manager = new HighscoreManager ();
network_manager = new NetworkManager ();
@ -1181,7 +1174,7 @@ void cleanSuperTuxKart()
if(grand_prix_manager) delete grand_prix_manager;
if(highscore_manager) delete highscore_manager;
if(attachment_manager) delete attachment_manager;
if(item_manager) delete item_manager;
ItemManager::removeTextures();
if(powerup_manager) delete powerup_manager;
if(projectile_manager) delete projectile_manager;
if(kart_properties_manager) delete kart_properties_manager;
@ -1292,7 +1285,7 @@ int main(int argc, char *argv[] )
}
Referee::init();
powerup_manager -> loadAllPowerups ();
item_manager -> loadDefaultItems();
ItemManager::loadDefaultItemMeshes();
GUIEngine::addLoadingIcon( irr_driver->getTexture(
file_manager->getGUIDir() + "/gift.png") );

View File

@ -146,9 +146,9 @@ void RaceState::receive(ENetPacket *pkt)
if(hi.m_item_id==-1) // Rescue triggered
new RescueAnimation(world->getKart(hi.m_kart_id));
else
item_manager->collectedItem(hi.m_item_id,
world->getKart(hi.m_kart_id),
hi.m_add_info);
ItemManager::get()->collectedItem(hi.m_item_id,
world->getKart(hi.m_kart_id),
hi.m_add_info);
}
// 3. Projectiles

View File

@ -872,7 +872,7 @@ public:
{
// Random kart
scene::IMesh* model =
item_manager->getItemModel(Item::ITEM_BONUS_BOX);
ItemManager::get()->getItemModel(Item::ITEM_BONUS_BOX);
w3->clearModels();
w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f),
Vec3(35.0f, 35.0f, 35.0f) );

View File

@ -123,7 +123,7 @@ void Track::reset()
{
m_ambient_color = m_default_ambient_color;
CheckManager::get()->reset(*this);
item_manager->reset();
ItemManager::get()->reset();
m_track_object_manager->reset();
} // reset
@ -134,10 +134,10 @@ void Track::reset()
void Track::cleanup()
{
QuadGraph::destroy();
ItemManager::destroy();
ParticleKindManager::get()->cleanUpTrackSpecificGfx();
item_manager->cleanup();
for(unsigned int i=0; i<m_animated_textures.size(); i++)
{
delete m_animated_textures[i];
@ -200,8 +200,6 @@ void Track::cleanup()
}
m_detached_cached_meshes.clear();
QuadGraph::destroy();
if(m_mini_map)
{
assert(m_mini_map->getReferenceCount()==1);
@ -341,6 +339,8 @@ void Track::loadTrackInfo()
} // loadTrackInfo
//-----------------------------------------------------------------------------
/** Loads all curves from the XML node.
*/
void Track::loadCurves(const XMLNode &node)
{
for(unsigned int i=0; i<node.getNumNodes(); i++)
@ -351,6 +351,12 @@ void Track::loadCurves(const XMLNode &node)
} // loadCurves
//-----------------------------------------------------------------------------
/** Loads all music information for the specified files (which is taken from
* the track.xml file).
* \param filenames List of filenames to load.
* \param music On return contains the music information object for the
* specified files.
*/
void Track::getMusicInformation(std::vector<std::string>& filenames,
std::vector<MusicInformation*>& music )
{
@ -427,16 +433,18 @@ void Track::loadQuadGraph(unsigned int mode_id, const bool reverse)
}
else
{
//Check whether the hardware can do nonsquare or non power-of-two textures
video::IVideoDriver* const video_driver = irr_driver->getVideoDriver();
bool nonpower = video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
bool nonsquare = video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE);
//Check whether the hardware can do nonsquare or
// non power-of-two textures
video::IVideoDriver* const video_driver = irr_driver->getVideoDriver();
bool nonpower = video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
bool nonsquare =
video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE);
//Create the minimap resizing it as necessary.
m_mini_map=
QuadGraph::get()->makeMiniMap(World::getWorld()->getRaceGUI()
->getMiniMapSize().getOptimalSize(!nonpower, !nonsquare),
"minimap::"+m_ident);
//Create the minimap resizing it as necessary.
core::dimension2du size = World::getWorld()->getRaceGUI()
->getMiniMapSize()
.getOptimalSize(!nonpower,!nonsquare);
m_mini_map = QuadGraph::get()->makeMiniMap(size, "minimap::"+m_ident);
}
} // loadQuadGraph
@ -1070,7 +1078,7 @@ void Track::update(float dt)
m_animated_textures[i]->update(dt);
}
CheckManager::get()->update(dt);
item_manager->update(dt);
ItemManager::get()->update(dt);
} // update
@ -1235,6 +1243,8 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
// map to.
if (!m_is_arena && !m_is_cutscene) loadQuadGraph(mode_id, reverse_track);
ItemManager::create();
// Set the default start positions. Node that later the default
// positions can still be overwritten.
float forwards_distance = 1.5f;
@ -1750,7 +1760,7 @@ void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,
// around.
//Vec3 normal(0.7071f, 0, 0.7071f);
Vec3 normal(0, 1, 0);
item_manager->newItem(type, loc, normal);
ItemManager::get()->newItem(type, loc, normal);
} // itemCommand
// ----------------------------------------------------------------------------

View File

@ -190,7 +190,7 @@ TrackObject::TrackObject(const XMLNode &xml_node)
if (trigger_when_near)
{
item_manager->newItem(m_init_xyz, trigger_distance, this);
ItemManager::get()->newItem(m_init_xyz, trigger_distance, this);
}
}
else