Segfault after erasing instanced from map

Started by
4 comments, last by ToohrVyk 16 years ago
Well, I've given this my all, but it just isn't enough. I coded callback, an entire object system, everything it took to make C++ higher level. When I went to test my final callback implementation, it segfaulted. Why? Because it turns out instance_destroy leaves something behind in the map of instances, which I'm assuming is executed later anyway as I iterate through the map. Not sure how, here is some code. Note: I think this is probably resulting from the fact that an object is supposed to destroy itself. I've heard of self destruction like that before, but the jury was out every time... GMobject.h
/***********************************************************************************                                                                              **
**  Copyright (C) 2008 Josh Ventura                                             **
**                                                                              **
**  This file is a part of the ENIGMA Development Environment.                  **
**                                                                              **
**                                                                              **
**  ENIGMA is free software: you can redistribute it and/or modify it under the **
**  terms of the GNU General Public License as published by the Free Software   **
**  Foundation, version 3 of the license or any later version.                  **
**                                                                              **
**  This application and its source code is distributed AS-IS, WITHOUT ANY      **
**  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS   **
**  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more       **
**  details.                                                                    **
**                                                                              **
**  You should have recieved a copy of the GNU General Public License along     **
**  with this code. If not, see <http://www.gnu.org/licenses/>                  **
**                                                                              **
**  ENIGMA is an environment designed to create games and other programs with a **
**  high-level, fully compilable language. Developers of ENIGMA or anything     **
**  associated with ENIGMA are in no way responsible for its users or           **
**  applications created by its users, or damages caused by the environment     **
**  or programs made in the environment.                                        **                      
**                                                                              **
\*********************************************************************************/

int __ENIGMA_maxid=100001;
int __ENIGMA_instancecount=0;
int __ENIGMA_id_current=0;

double __ENIGMA_newinst_x,__ENIGMA_newinst_y;int __ENIGMA_newinst_obj,__ENIGMA_newinst_id;

struct __object
{
    #include "IDE_EDIT_inherited_locals.h"
    #include "IDE_EDIT_withdeclarations.h"
    #include "IDE_EDIT_scriptdeclarations.h"
    
    virtual int instance_destroy();
    
    virtual void __myevent_create()        {}
    
    virtual void __myevent_gamestart()     {}
    virtual void __myevent_roomstart()     {}
    virtual void __myevent_beginstep()     {}
    virtual void __myevent_alarm()         {}
    virtual void __myevent_keyboard()      {}
    virtual void __myevent_keypress()      {}
    virtual void __myevent_keyrelease()    {}
    virtual void __myevent_mouse()         {}
    virtual void __myevent_step()          {}
    virtual void __myevent_pathend()       {}
    virtual void __myevent_outsideroom()   {}
    virtual void __myevent_boundary()      {}
    virtual void __myevent_collision()     {}
    virtual void __myevent_nomorelives()   {}
    virtual void __myevent_nomorehealth()  {}
    virtual void __myevent_endstep()       {}
    virtual void __myevent_draw()          { draw_sprite(sprite_index,image_index,x,y); }
    virtual void __myevent_endanimation()  {}
    virtual void __myevent_roomend()       {}
    virtual void __myevent_gameend()       {}
    
    virtual void __myevent_destroy()       {}
};

struct __global:public __object
{
    #include "IDE_EDIT_withdeclarations.h"
};
__object* __ENIGMA_global_instance=new __global;

void __ENIGMA_constructor(__object* instance)
{
     instance->x = __ENIGMA_newinst_x;
     instance->y = __ENIGMA_newinst_y;
     instance->object_index = __ENIGMA_newinst_obj;
     instance->id = __ENIGMA_newinst_id;
     
     __ENIGMA_instancecount++;
     instance_count++;
}

#define ev_create     0
#define ev_destroy    1
#define ev_alarm      2
#define ev_step       3
#define ev_collision  4
#define ev_keyboard   5
#define ev_mouse      6
#define ev_other      7
#define ev_draw       8
#define ev_keypress   9
#define ev_keyrelease 10

#include "IDE_EDIT_objectdeclarations.h"

std::map<unsigned int,__object*> __instance_list;
std::map<unsigned int,__object*>::iterator __instance_iterator;
std::map<unsigned int,__object*>::iterator __instance_event_iterator;
std::map<unsigned int,__object*>::iterator __instance_with_iterator;


__object* __ENIGMA_int2object(double intr)
{
    int integer=(int)intr;
    if (integer<=100000)
    {
     if (integer>=0)
     {
       for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
       {
           if ((*__instance_iterator).second->object_index==integer)
           {
              return (*__instance_iterator).second;
           }
       }
       return new __object;
     }
     else
     {
         if (integer==-1)
         return (*__instance_iterator).second;
         if (integer==-3)
         {
         __instance_iterator=__instance_list.begin();
         return (*__instance_iterator).second;
         }
         if (integer==-5)
         return __ENIGMA_global_instance;
         return new __object;
         
     }
    }
    else
    {
       if (__instance_list.find(integer) != __instance_list.end())
       return __instance_list[integer];
       else
       return new __object;
    }
}

#include "GMinstance.h"
#include "GMroomsystem.h"

#include "IDE_EDIT_objectfunctionality.h"
#include "IDE_EDIT_withfunctionality.h"



GMinstance.h
/***********************************************************************************                                                                              **
**  Copyright (C) 2008 Josh Ventura                                             **
**                                                                              **
**  This file is a part of the ENIGMA Development Environment.                  **
**                                                                              **
**                                                                              **
**  ENIGMA is free software: you can redistribute it and/or modify it under the **
**  terms of the GNU General Public License as published by the Free Software   **
**  Foundation, version 3 of the license or any later version.                  **
**                                                                              **
**  This application and its source code is distributed AS-IS, WITHOUT ANY      **
**  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS   **
**  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more       **
**  details.                                                                    **
**                                                                              **
**  You should have recieved a copy of the GNU General Public License along     **
**  with this code. If not, see <http://www.gnu.org/licenses/>                  **
**                                                                              **
**  ENIGMA is an environment designed to create games and other programs with a **
**  high-level, fully compilable language. Developers of ENIGMA or anything     **
**  associated with ENIGMA are in no way responsible for its users or           **
**  applications created by its users, or damages caused by the environment     **
**  or programs made in the environment.                                        **                      
**                                                                              **
\*********************************************************************************/

/**Instance functions**********************************************************
int instance_create(ARG x,ARG2 y,ARG3 object)
int instance_destroy()
bool instance_exists(ARG obj)
int instance_find(ARG obj,ARG2 n)
int instance_number(ARG obj)
int instance_position(ARG x,ARG2 y,ARG3 obj)
int instance_nearest(ARG x,ARG2 y,ARG3 obj)
int instance_furthest(ARG x,ARG2 y,ARG3 obj)


\******************************************************************************/

int instance_create(double x,double y,double object)
{
    int a=__ENIGMA_maxid;
    
    int obj=(int) object;
    
    __ENIGMA_maxid++;
    
    __ENIGMA_newinst_id=a;
    __ENIGMA_newinst_obj=obj;
    __ENIGMA_newinst_x=x;
    __ENIGMA_newinst_y=y;
    
    switch (obj)
    {
       #include "IDE_EDIT_object_switch.h"
       default:
            #if SHOWERRORS
            show_error("Object does not exist...",0);
            #endif
            return -1;
    }
    
    return a;
}

int __object::instance_destroy()
{
   __instance_list.erase((const unsigned int)id);
   
   //dispstr("",id);
   
   __ENIGMA_instancecount--;
   instance_count--;
     
   return 0;
}

bool instance_exists(double obj)
{
     int instance=(int) obj;
     if (instance>100000)
     {
        return (__instance_list.find(instance) != __instance_list.end());
     }
     else if (instance>=0)
     {
       for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
       {
           if ((*__instance_iterator).second->object_index==instance)
           {
              return 1;
           }
       }
       return 0;
     }
     else
     {
         switch (instance)
         {
            case -1:
                 return (__instance_list.find((int)((*__instance_iterator).second->id)) != __instance_list.end());
                 break;
            case -3:
                 return (__instance_list.size()>0);
                 break;
            default:
                 return 0;
                 break;
         }
     }
     return 0;
}

int instance_find(double obj,double n)
{
   int objind=(int)obj;
   int num=(int)n;
   int nth=0;
   for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
   {
       if ((*__instance_iterator).second->object_index==objind)
       {
          nth++;
          if (nth>num)
          return (int) (*__instance_iterator).second->id;
       }
   }
   return -4;
}
int instance_number(double obj)
{
   int objind=(int)obj;
   int n=0;
   for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
   {
       if ((*__instance_iterator).second->object_index==objind)
       {
          n++;
       }
   }
   return n;
}


int instance_position(double x,double y,double obj)
{
    int objind=(int) obj;
    int xl,yl;
    int xc=(int)x,yc=(int)y;
    
    for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
    {
    if (((*__instance_iterator).second->object_index==objind) || objind==-3)
    {
       xl=(int)(*__instance_iterator).second->x;
       yl=(int)(*__instance_iterator).second->y;
       
       if (xl==xc && yl==yc)
       return (int)(*__instance_iterator).second->id;
    }
    }
    return -4;
}

int instance_nearest(double x,double y,double obj)
{
    double dist_lowest=100000,retid=0;
    bool found=0;
    int objind=(int) obj;
    int xl,yl;
    double dstclc;
    
    for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
    {
    if (((*__instance_iterator).second->object_index==objind) || objind==-3)
    {
       xl=(int)(*__instance_iterator).second->x;
       yl=(int)(*__instance_iterator).second->y;
       dstclc=std::sqrt(xl*xl+yl*yl);
       if (dstclc<dist_lowest || found==0)
       {
          dist_lowest=dstclc;
          retid= (*__instance_iterator).second->id;
          found=1;
       }
    }
    }
    
    return (int)retid;
}
int instance_furthest(double x,double y,double obj)
{
    double dist_highest=0,retid=0;
    bool found=0;
    int objind=(int) obj;
    int xl,yl;
    double dstclc;
    
    for (__instance_iterator=__instance_list.begin(); __instance_iterator != __instance_list.end(); __instance_iterator++)
    {
    if (((*__instance_iterator).second->object_index==objind) || objind==-3)
    {
       xl=(int)(*__instance_iterator).second->x;
       yl=(int)(*__instance_iterator).second->y;
       dstclc=std::sqrt(xl*xl+yl*yl);
       if (dstclc>dist_highest || found==0)
       {
          dist_highest=dstclc;
          retid= (*__instance_iterator).second->id;
          found=1;
       }
    }
    }
    
    return (int)retid;
}


//int instance_place(x,y,obj)
//int instance_copy(performevent)
//instance_change(obj,perf)



IDE_EDIT_object_switch.h
case 0: 
 __instance_list[a]=new __ENIGMAOBJ_obj_0; 
 break; 
case 1: 
 __instance_list[a]=new __ENIGMAOBJ_obj_1; 
 break; 



IDE_EDIT_objectfunctionality.h
//This file was generated by the ENIGMA Development Environment.

void __ENIGMAOBJ_obj_0::__myevent_create() 
{
 __ENIGMA_int2object(global)->base=128;
 
}

void __ENIGMAOBJ_obj_0::__myevent_mouse() 
{
if (__ENIGMA_mousestatus[1] == 1 && __ENIGMA_last_mousestatus[1] == 0)
{ 
int a=instance_create(mouse_x,mouse_y,obj_1);
__ENIGMA_int2object(a)->color=c_red;
}
if (__ENIGMA_mousestatus[2] == 1 && __ENIGMA_last_mousestatus[2] == 0)
{ 
int a=instance_create(mouse_x,mouse_y,obj_1);
__ENIGMA_int2object(a)->color=c_blue;
}
if (__ENIGMA_mousestatus[0] == 0 && __ENIGMA_last_mousestatus[0] == 1)
{ 
int a=instance_create(mouse_x,mouse_y,obj_1);
__ENIGMA_int2object(a)->color=c_yellow;
}
for (int __ACALLBACKITERATOR=__ENIGMA_mousewheel;__ACALLBACKITERATOR>0;__ACALLBACKITERATOR-=120)
{ 
__ENIGMA_int2object(global)->base+=16;
}
for (int __ACALLBACKITERATOR=(-__ENIGMA_mousewheel);__ACALLBACKITERATOR>0;__ACALLBACKITERATOR-=120)
{ 
__ENIGMA_int2object(global)->base-=16;
}
}

void __ENIGMAOBJ_obj_0::__myevent_draw() 
{
 draw_sprite(sprite_index,image_index,x,y);
int a=instance_create(mouse_x,mouse_y,obj_1);
__ENIGMA_int2object(a)->color=c_fuchsia;
 
}

void __ENIGMAOBJ_obj_1::__myevent_create() 
{
 int radius=0;
 
}

void __ENIGMAOBJ_obj_1::__myevent_draw() 
{
 radius+=3;
draw_set_color(color);
draw_circle(x,y,radius,1);
if (radius>__ENIGMA_int2object(global)->base)
instance_destroy();
 
}




events.h (executed every frame):
/***********************************************************************************                                                                              **
**  Copyright (C) 2008 Josh Ventura                                             **
**                                                                              **
**  This file is a part of the ENIGMA Development Environment.                  **
**                                                                              **
**                                                                              **
**  ENIGMA is free software: you can redistribute it and/or modify it under the **
**  terms of the GNU General Public License as published by the Free Software   **
**  Foundation, version 3 of the license or any later version.                  **
**                                                                              **
**  This application and its source code is distributed AS-IS, WITHOUT ANY      **
**  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS   **
**  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more       **
**  details.                                                                    **
**                                                                              **
**  You should have recieved a copy of the GNU General Public License along     **
**  with this code. If not, see <http://www.gnu.org/licenses/>                  **
**                                                                              **
**  ENIGMA is an environment designed to create games and other programs with a **
**  high-level, fully compilable language. Developers of ENIGMA or anything     **
**  associated with ENIGMA are in no way responsible for its users or           **
**  applications created by its users, or damages caused by the environment     **
**  or programs made in the environment.                                        **                      
**                                                                              **
\*********************************************************************************/


void ENIGMA_events(void)
{
    __ENIGMA_update_globals();
    
    
    #ifdef __ENIGMA_parent_bstep
       __ENIGMA_parent_beginstep();
    #endif
    
    int __ENIGMA_event_current, view_current;
            
            #ifdef __ENIGMAEVENT_roomstart
            __ENIGMA_event_current=1;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_roomstart; }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_beginstep
            __ENIGMA_event_current=2;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_beginstep(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_alarm
            __ENIGMA_event_current=3;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_alarm; }
            __ENIGMA_update_globals();
            #endif
            
            {
                 #ifdef __ENIGMAEVENT_keyboard
                 __ENIGMA_event_current=4;
                 for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
                 { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
                   (*__instance_event_iterator).second->__myevent_keyboard(); }
                 __ENIGMA_update_globals();
                 #endif
                 
                 #ifdef __ENIGMAEVENT_keypress
                 __ENIGMA_event_current=5;
                 for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
                 { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
                   (*__instance_event_iterator).second->__myevent_keypress (); }
                 __ENIGMA_update_globals();
                 #endif
                 
                 #ifdef __ENIGMAEVENT_keyrelease
                 __ENIGMA_event_current=6;
                 for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
                 { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
                   (*__instance_event_iterator).second->__myevent_keyrelease(); }
                 #endif
            }
            
            {
                 #ifdef __ENIGMAEVENT_mouse
                 __ENIGMA_event_current=7;
                 for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
                 { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
                   (*__instance_event_iterator).second->__myevent_mouse(); }
                 __ENIGMA_update_globals();
                 #endif
            }
            
            #ifdef __ENIGMAEVENT_step
            __ENIGMA_event_current=8;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_step(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_pathend
            __ENIGMA_event_current=9;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_pathend(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_outsideroom
            __ENIGMA_event_current=10;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_outsideroom(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_boundary
            __ENIGMA_event_current=11;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_boundary(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_collision
            __ENIGMA_event_current=12;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_collision(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_nomorelives
            __ENIGMA_event_current=13;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_nomorelives(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_nomorehealth
            __ENIGMA_event_current=14;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_nomorehealth(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_endstep
            __ENIGMA_event_current=15;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_endstep(); }
            __ENIGMA_update_globals();
            #endif
            
            __ENIGMA_update_globals();
            
            if (!view_enabled)
            {
                if (background_showcolor)
                {
                    int __clearcolor=(int)__negmod((int)background_color,16777215);
                    glClearColor(__GETR(__clearcolor)/255.0,__GETG(__clearcolor)/255.0,__GETB(__clearcolor)/255.0, 1);
                    glClear(GL_COLOR_BUFFER_BIT);
                }
                
                __ENIGMA_event_current=16;
                for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
                { 
                    __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
                    (*__instance_event_iterator).second->__myevent_draw(); 
                }
                __ENIGMA_update_globals();
            }
            else
            for (view_current=0; view_current<7; view_current++)
            {
                if (background_showcolor)
                {
                    int __clearcolor=(int)__negmod((int)background_color,16777215);
                    glClearColor(__GETR(__clearcolor)/255.0,__GETG(__clearcolor)/255.0,__GETB(__clearcolor)/255.0, 1);
                    glClear(GL_COLOR_BUFFER_BIT);
                }
                
                __ENIGMA_event_current=16;
                for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
                { 
                    __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
                    (*__instance_event_iterator).second->__myevent_draw(); 
                }
                __ENIGMA_update_globals();
            }
            SwapBuffers(__window_hDC);
            
            
            
            
            
            #ifdef __ENIGMAEVENT_endanimation
            __ENIGMA_event_current=17;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_endanimation(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_roomend
            __ENIGMA_event_current=18;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_roomend(); }
            __ENIGMA_update_globals();
            #endif
            
            #ifdef __ENIGMAEVENT_gameend
            __ENIGMA_event_current=19;
            for (__instance_event_iterator=__instance_list.begin(); __instance_event_iterator != __instance_list.end(); __instance_event_iterator++)
            { __ENIGMA_id_current=(int)((*__instance_event_iterator).second->id); 
              (*__instance_event_iterator).second->__myevent_gameend(); }
            __ENIGMA_update_globals();
            #endif
    
    #ifdef __ENIGMA_parent_estep
       __ENIGMA_parent_endstep();
    #endif
    
    
    for (int i=0;i<256;i++)
    {
      __ENIGMA_last_keybdstatus=__ENIGMA_keybdstatus;
    }
    for (int i=0;i<3;i++) { __ENIGMA_last_mousestatus=__ENIGMA_mousestatus; }
    __ENIGMA_mousewheel=0;
    fps=__getfps();
    
    Sleep(1);
}



That's a lot of code. If you need more, ask here, or go to www.enigma-dev.org and download one of the Release 2 things, all of which will be slightly outdated. Thanks for any help. I've pretty much given up. -Josh [Edited by - Josh@Dreamland on April 19, 2008 5:44:39 PM]
Advertisement
1° Same remark, again, with those '__'.

2° Declaring variables at the top of the function is already annoying enough, but declaring them at the global scope is both annoying and asking for trouble (by making all your functions non-reentrant).

3° Despite all your claims to be higher-level, you still have heaps of global variables lying around. No matter how willing and competent I am, there's no way I even attempt to debug such a horror.

4° Don't use #defines to define integer constants. And don't use integer constants where an enumeration would be the perfect fit. Namely, your events. In fact, your huge set of virtual functions could easily be represented in a more lightweight manner using that enumeration.

5° What's the point of all the dark magic to find an integer by its key in a map without using the map to find the element?

Phew, that was only your first snippet.

6° Are you casting an integer identifier to a double and back? Yes, you are. Are you insane? I guess so.

7° Your third snippet is a memory leak if your function is called several times with the same argument. At least pretend to do some memory-checking...

Either way, your code needs a massive design and readability re-haul. Less globals, less useless underscores and namespace-like modificiations everywhere, more factoring of common code, less C idioms, less manual memory management, more encapsulation... The first step would be moving those globals to either local variables in functions (all those iterators, for instance) or to members of objects. The second step would be dropping naked pointers and using smart pointers instead... although all of these are still merely band-aids over the underlying issue that you have an overcomplicated and bloated juggernaut on top of what seems to be ultimately a very simple design that could be easily solved with a plain old:

enum Events { ... };typedef std::map< Event, boost::function0<void> > Object;typedef std::map<unsigned int, Object> World>;
Those underscores could be replaced. But the global scope is necessary.

I've never had a problem coding for myself. This is part of an engine. It needs to be out of the way or users of the engine could easily screw something up on accident.

The third snippet plugs into the second. I don't see how that would lead to memory leak when I'm storing everything in a map to be freed as instance_destroy is called.

This is meant to be high level in the sense that the user doesn't have to see any of this. It is intended to keep to itself and stay out of the way, manipulated further behind the scenes as the user calls higher level functions.

I don't know how to explain my intentions to you. Download the no GCC version on my website and watch what it does to the code you enter.

I'll look into enumerations. Keep in mind this is code-generated, and must require little intelligent thought.
Your code is effectively useless. It is unreadable. I mean, most implementations of the C++ standard library I've come across are easier to read, and that is saying something. I have to agree with ToohrVyk, the spirit is willing, but the eyes have melted already.

Quote:
It needs to be out of the way or users of the engine could easily screw something up on accident.


Use a real C++ namespace, and tell people not to use it for their own code. simple.
Beyond the considerations cited by ToohrVyk and rip-off, I am pretty sure that using identifiers starting with a double underscore at global scope is a really bad idea. I wouldn't swear to it actually being illegal, but it sure isn't clever, and '__global' and '__object' is just asking for a collision with a built-in compiler token.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Quote:Original post by Josh@Dreamland
Those underscores could be replaced. But the global scope is necessary.

I've never had a problem coding for myself. This is part of an engine. It needs to be out of the way or users of the engine could easily screw something up on accident.


boost is a pretty widely used library (to say the least) yet it does not resort to identifier prefix shenanigans to avoid collisions with user identifiers. It just places all private identifiers in the boost::detail namespace, and that's all.

Do the same: place your public interface in namespace enigma, and the private details in enigma::detail. Problem solved.

Quote:The third snippet plugs into the second. I don't see how that would lead to memory leak when I'm storing everything in a map to be freed as instance_destroy is called.


Long story short:

a = new Foo();a = new Foo();delete a; // The second instance is deleted, the first is leaked


Quote:I'll look into enumerations. Keep in mind this is code-generated, and must require little intelligent thought.


I'm a language semantician. My job is to design compilers, so I tend to have a fairly high level of expectation from compilers. In your case, it seems that your compiler design is jumbled. In practice, a compiler will generate code that use hand-written code which uses high encapsulation and very clear invariants that are thoroughly documented. That hand-written code would be grouped together in 'runtime' files which are then included and used by the generated code.

Your code, however, bears no trace of this... you should perform that split beforehand, so that the generated code does not contain any unrelated functionality.

This topic is closed to new replies.

Advertisement