размер контейнера в map имеет размер 1. [c++]
Есть статические класс. в нем много контейнеров map. Я например создаю кнопку и помещаю её в сцену с слоем 1. то есть в 0 слое у меня спрайты. а в 1 слое кнопки. я добавляю вот так.
Scene<Button>::load ( btn, 1 );. и в этом слое появляются эти кнопки. но есть проблема. я например не хочу задумывать на каком слое есть виджеты и пишу в рендере так.
Scene<Button>::draw0 ( );
Scene<Actor>::draw0 ( );
Scene<Box>::draw0 ( );
Scene<Button>::draw1 ( );
Scene<Actor>::draw1 ( );
Scene<Box>::draw1 ( );
но игра segfault. я проверяю и оказывается что bmap0, bmap0 это map кнопки в слое 0, имеет размер 1 и пытается нарисовать объект. но я в этот слой кнопку не помещал. помещал только Actor. Блин, если я покажу код, то вы не захочите смотреть его наверное. ну ладно, покажу.
#ifndef __SCENE_H__
#define __SCENE_H__
#include <map>
#include <string>
#include <stdlib.h>
#include "actor.h"
#include "sprite.h"
#include "button.h"
#include "progress.h"
#include "font.h"
template <typename T>
class Scene {
public:
static inline std::map <std::string, Sprite *> map0;
static inline std::map <std::string, Sprite *> map1;
static inline std::map <std::string, Sprite *> map2;
static inline std::map <std::string, Button *> bmap0;
static inline std::map <std::string, Button *> bmap1;
static inline std::map <std::string, Button *> bmap2;
static inline std::map <std::string, Actor *> amap0;
static inline std::map <std::string, Actor *> amap1;
static inline std::map <std::string, Actor *> amap2;
static inline std::map <std::string, Box *> bbmap0;
static inline std::map <std::string, Box *> bbmap1;
static inline std::map <std::string, Box *> bbmap2;
static void clear ( Sprite *ssp ) {
map0.clear ( );
map1.clear ( );
map2.clear ( );
}
static void clear ( Button *ssp ) {
bmap0.clear ( );
bmap1.clear ( );
bmap2.clear ( );
}
static void clear ( Actor *ssp ) {
amap0.clear ( );
amap1.clear ( );
amap2.clear ( );
}
static void clear ( Box *ssp ) {
bbmap0.clear ( );
bbmap1.clear ( );
bbmap2.clear ( );
}
static void init ( ) {
T *clean;
clear ( clean );
}
static void get_view0 ( Box **view ) {
bbmap0 [ (*view)->name ] = *view;
}
static void get_view1 ( Box **view ) {
bbmap1 [ (*view)->name ] = *view;
}
static void get_view2 ( Box **view ) {
bbmap2 [ (*view)->name ] = *view;
}
static void get_view0 ( Actor **view ) {
amap0 [ (*view)->name ] = *view;
}
static void get_view1 ( Actor **view ) {
amap1 [ (*view)->name ] = *view;
}
static void get_view2 ( Actor **view ) {
amap2 [ (*view)->name ] = *view;
}
static void get_view0 ( Button **view ) {
bmap0 [ (*view)->name ] = *view;
}
static void get_view1 ( Button **view ) {
bmap1 [ (*view)->name ] = *view;
}
static void get_view2 ( Button **view ) {
bmap2 [ (*view)->name ] = *view;
}
static void get_view0 ( Sprite **view ) {
map0 [ (*view)->name ] = *view;
}
static void get_view1 ( Sprite **view ) {
map1 [ (*view)->name ] = *view;
}
static void get_view2 ( Sprite **view ) {
map2 [ (*view)->name ] = *view;
}
static void load ( T *obj, const int layer ) {
switch ( layer ) {
case 0: get_view0 ( &obj ); break;
case 1: get_view1 ( &obj ); break;
case 2: get_view2 ( &obj ); break;
default: break;
}
}
static void find_obj ( Box **view, const std::string str ) {
*view = bbmap0 [ str ];
if ( *view ) return;
*view = bbmap1 [ str ];
if ( *view ) return;
*view = bbmap2 [ str ];
if ( *view ) return;
}
static void find_obj ( Actor **view, const std::string str ) {
*view = amap0 [ str ];
if ( *view ) return;
*view = amap1 [ str ];
if ( *view ) return;
*view = amap2 [ str ];
if ( *view ) return;
}
static void find_obj ( Sprite **view, const std::string str ) {
*view = map0 [ str ];
if ( *view ) return;
*view = map1 [ str ];
if ( *view ) return;
*view = map2 [ str ];
if ( *view ) return;
}
static void find_obj ( Button **view, const std::string str ) {
*view = bmap0 [ str ];
if ( *view ) return;
*view = bmap1 [ str ];
if ( *view ) return;
*view = bmap2 [ str ];
if ( *view ) return;
}
static T *get_obj ( const char *str ) {
T *obj;
std::string s = str;
find_obj ( &obj, s );
return obj;
}
static void drawing_f0 ( Sprite *ssp ) {
std::map<std::string, Sprite *>::iterator it = map0.begin();
while ( it != map0.end() ) {
it->second->draw ( );
it++;
}
}
static void drawing_f0 ( Button *ssp ) {
std::map<std::string, Button *>::iterator bit = bmap0.begin();
while ( bit != bmap0.end() ) {
bit->second->draw ( );
bit++;
}
}
static void drawing_f0 ( Actor *ssp ) {
std::map<std::string, Actor *>::iterator ait = amap0.begin();
while ( ait != amap0.end() ) {
if ( !ait->second->is_single ) ait->second->draw_single ( );
else ait->second->draw ( );
ait++;
}
}
static void drawing_f0 ( Box *ssp ) {
std::map<std::string, Box *>::iterator bbit = bbmap0.begin();
while ( bbit != bbmap0.end() ) {
bbit->second->draw ( );
bbit++;
}
}
static void draw0 ( ) {
T *drawing;
drawing_f0 ( drawing );
}
static void draw1 ( ) {
std::map<std::string, Sprite *>::iterator it = map1.begin();
while ( it != map1.end() ) {
it->second->draw ( );
it++;
}
std::map<std::string, Button *>::iterator bit = bmap1.begin();
while ( bit != bmap1.end() ) {
bit->second->draw ( );
bit++;
}
std::map<std::string, Actor *>::iterator ait = amap1.begin();
while ( ait != amap1.end() ) {
if ( !ait->second->is_single ) ait->second->draw_single ( );
else ait->second->draw ( );
ait++;
}
std::map<std::string, Box *>::iterator bbit = bbmap1.begin();
while ( bbit != bbmap1.end() ) {
bbit->second->draw ( );
bbit++;
}
}
static void draw2 ( ) {
std::map<std::string, Sprite *>::iterator it = map2.begin();
while ( it != map2.end() ) {
it->second->draw ( );
it++;
}
std::map<std::string, Button *>::iterator bit = bmap2.begin();
while ( bit != bmap2.end() ) {
bit->second->draw ( );
bit++;
}
std::map<std::string, Actor *>::iterator ait = amap2.begin();
while ( ait != amap2.end() ) {
if ( !ait->second->is_single ) ait->second->draw_single ( );
else ait->second->draw ( );
ait++;
}
std::map<std::string, Box *>::iterator bbit = bbmap2.begin();
while ( bbit != bbmap2.end() ) {
bbit->second->draw ( );
bbit++;
}
}
struct sbutton {
Button *btn;
std::string signal;
void *data;
void (*func) ( Button *btn, void *data );
};
static inline int count;
static inline int index;
static inline int start = 0;
typedef struct sbutton *sbutton_ptr;
static inline sbutton_ptr *sb;
static void get_signal ( Button *btn, std::string &signal, void (*func) ( Button *btn, void *data ), void *data ) {
count++;
sb = ( sbutton_ptr * ) realloc ( sb, sizeof ( sbutton_ptr ) * count );
sb[index] = ( struct sbutton * ) calloc ( 1, sizeof ( struct sbutton ) );
sb[index]->btn = btn;
sb[index]->signal = signal;
sb[index]->data = data;
sb[index]->func = func;
index++;
}
static void signal ( T *widget, std::string signal, void (*func) ( Button *btn, void *data ), void *data ) {
if ( start == 0 ) {
sb = ( sbutton_ptr * ) calloc ( 0, sizeof ( sbutton_ptr ) );
start = 1;
count = 0;
index = 0;
}
get_signal ( widget, signal, func, data );
}
static void event_signal_click ( int x, int y ) {
int ss = 0;
for ( int i = 0; i < count; i++ ) {
Button *btn = sb[i]->btn;
if ( x >= btn->box->x && x <= btn->box->box_width + btn->box->x ) {
if ( y >= btn->box->y && y <= btn->box->box_height + btn->box->y ) {
if ( sb[i]->signal == "click" ) {
btn->toggled = true;
sb[i]->func( btn, sb[i]->data );
ss = 1;
}
}
}
if ( ss == 0 ) {
btn->toggled = false;
}
ss = 1;
}
}
static void event_signal_over ( int x, int y ) {
int ss = 0;
for ( int i = 0; i < count; i++ ) {
Button *btn = sb[i]->btn;
if ( x >= btn->box->x && x <= btn->box->box_width + btn->box->x ) {
if ( y >= btn->box->y && y <= btn->box->box_height + btn->box->y ) {
if ( sb[i]->signal == "over" ) {
btn->over = true;
sb[i]->func( btn, sb[i]->data );
return;
}
}
}
if ( ss == 0 ) {
btn->is_second = false;
}
ss = 1;
}
}
private:
};
#endif
Ответы (1 шт):
Когда Вы пишите *view = bbmap0 [ str ]; то Вы либо получаете существующий объект (если он есть) либо (барабанная дробь) если элемента нет - он будет создан, для него будет вызван дефолтный конструктор!!! И естественно в этом случае у Вас будет мапа с одним элементом и Ваш указатель будет нулевым.
Что делать? Самый простой вариант - воспользоваться count.
if (bbmap0.count(str) == 0) {
return;
}
*view = bbmap0 [ str ];
Второй способ - использовать find и итераторы.