porting procedural c++ to oo syntax

Started by
12 comments, last by Norman Barrows 9 years, 6 months ago

as a design exercise, i've decided to try porting the procedural c++ code for my new collision maps API to oo syntax.

the procedural code is an array of structs, routines that operate on a single struct, and routines that operate on the array:

 
//  ################################## COLLISION MAPS ################################################
 
 
//   CM stands for collision map
 
#define CM_SIZE 300
 
#define CM_CACHE_SIZE 20
 
 
struct CMrec
{
int active,age,mx,mz,cx,cz,data[CM_SIZE][CM_SIZE];
};
 
CMrec CM[CM_CACHE_SIZE];
 
 
void clear_CM(int cache_index)
{
ZeroMemory(&CM[cache_index],sizeof(CMrec));
}
 
 
void clear_CM_cache()
{
int a;
for (a=0; a<CM_CACHE_SIZE; a++)
    {
    clear_CM(a);
    }
}
 
 
 
 
 
 
void add_to_CM(int i,int x,int z,int rad,int value)
{
int x1,z1,x2,z2,x3,z3;
x1=x-rad;
x2=x+rad;
z1=z-rad;
z2=z+rad;
for (x3=x1; x3<=x2; x3++)
    {
    for (z3=z1; z3<=z2; z3++)
        {
if (x3 < 0)
    {
    continue;
    }
if (z3 < 0)
    {
    continue;
    }
if (x3 >= CM_SIZE)
    {
    continue;
    }
if (z3 >= CM_SIZE)
    {
    continue;
    }
CM[i].data[x3][z3]=value;
        }
    }
}
 
 
 
 
 
 
void add_tree_plantmap_to_CM(int i,int mx,int mz,int px,int pz)
{
int a,x,z,cx,cz,x2,z2,rad,value;
//  a      loop counter
//  x,z    location of the plant in the map sq
//   cx,xz   is the index of the collsion map the plant is in
//  x2,z2 is the location of the plant in the collision map
//  rad is the radius of the plant
//  for each plant in map, if in CM, add to CM
//  value is the value written to the CM
for (a=0; a<maxplants; a++)
    {
//  calc plant x z
    x=px*plantmapsize+plant[a].x;
    z=pz*plantmapsize+plant[a].z;
    if (waterinway(mx,mz,x,z))
        {
        continue;
        }
    if (storepit_in_way(mx,mz,x,z))
        {
        continue;
        }
//  calc CM index cx,cz
//  if its not in this CM, skip the plant
    cx=x/CM_SIZE;
    if (cx != CM[i].cx)
        {
        continue;
        }
    cz=z/CM_SIZE;
    if (cz != CM[i].cz)
        {
        continue;
        }
//  ok, plant is in CM index cx,cz
//  add it to the CM
//  calc x,z coords in the CM (x2,z2)
    x2=x-cx*CM_SIZE;
    z2=z-cz*CM_SIZE;
//  set radius
    rad=3;
//  set value. 1 = tree
    value=1;
//  add it!
    add_to_CM(i,x2,z2,rad,value);
    }
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void add_savanna_tree_plantmap_to_CM(int i,int mx,int mz,int px,int pz)
{
int a,x,z,cx,cz,x2,z2,rad,value,mod;
//  a      loop counter
//  x,z    location of the plant in the map sq
//   cx,xz   is the index of the collsion map the plant is in
//  x2,z2 is the location of the plant in the collision map
//  rad is the radius of the plant
//  for each plant in map, if in CM, add to CM
//  value is the value written to the CM
//  mod is the modulo value for haw many trees to add
if (mz < mapsize/3)
    {
    mod=SAVANNA_TREE_MOD;
    }
else
    {
    mod=NON_TROPICAL_SAVANNA_TREE_MOD;
    }
for (a=0; a<maxplants; a++)
    {
    if (a%mod != 0)
        {
        continue;
        }
//  calc plant x z
    x=px*plantmapsize+plant[a].x;
    z=pz*plantmapsize+plant[a].z;
    if (waterinway(mx,mz,x,z))
        {
        continue;
        }
    if (storepit_in_way(mx,mz,x,z))
        {
        continue;
        }
//  calc CM index cx,cz
//  if its not in this CM, skip the plant
    cx=x/CM_SIZE;
    if (cx != CM[i].cx)
        {
        continue;
        }
    cz=z/CM_SIZE;
    if (cz != CM[i].cz)
        {
        continue;
        }
//  ok, plant is in CM index cx,cz
//  add it to the CM
//  calc x,z coords in the CM (x2,z2)
    x2=x-cx*CM_SIZE;
    z2=z-cz*CM_SIZE;
//  set radius
    rad=3;
//  set value. 1 = tree
    value=1;
//  add it!
    add_to_CM(i,x2,z2,rad,value);
    }
}
 
 
 
 
 
 
void add_rock_plantmap_to_CM(int i,int mx,int mz,int px,int pz)
{
int a,x,z,cx,cz,x2,z2,rad,value,dx,dz;
location L;
//  a      loop counter
//  x,z    location of the plant in the map sq
//   cx,xz   is the index of the collsion map the plant is in
//  x2,z2 is the location of the plant in the collision map
//  rad is the radius of the plant
//  for each plant in map, if in CM, add to CM
//  value is the value written to the CM
for (a=0; a<maxplants; a++)
    {
//  skip every other rock
    if (a%2 == 1)
        {
        continue;
        }
//  calc rock x z
    x=px*plantmapsize+plant3[a].x;
    z=pz*plantmapsize+plant3[a].z;
//  stuff it in a location...
    L.mx=mx;
    L.mz=mz;
    L.x=(float)x;
    L.z=(float)z;
//  check for other terrain in way of the rock
    if (terrain_in_way_of_rock(&L))
        {
        continue;
        }
    if (waterinway(mx,mz,x,z))
        {
        continue;
        }
//  calc CM index cx,cz
//  if its not in this CM, skip the rock
    cx=x/CM_SIZE;
    if (cx != CM[i].cx)
        {
        continue;
        }
    cz=z/CM_SIZE;
    if (cz != CM[i].cz)
        {
        continue;
        }
//  ok, rock is in CM index cx,cz
//  add it to the CM
//  calc x,z coords in the CM (x2,z2)
    x2=x-cx*CM_SIZE;
    z2=z-cz*CM_SIZE;
//  calc radius
//  calc dx and dz dimesions of bbox
    dx=(int)(plant3[a].v2.x-plant3[a].v1.x);
    dz=(int)(plant3[a].v2.z-plant3[a].v1.z);
//  divide by 2 to get x and z radii of bbox
    dx/=2;
    dz/=2;
//  rad = avg of x and z radii of bbox
    dx+=dz;
    dx/=2;
    rad=dx;
//  set value. 3 = rock
    value=3;
//  add it!
    add_to_CM(i,x2,z2,rad,value);
    }
}
 
 
 
 
 
 
 
 
 
void add_fruittree_plantmap_to_CM(int i,int mx,int mz,int px,int pz)
{
int a,x,z,cx,cz,x2,z2,rad,value;
//  a      loop counter
//  x,z    location of the plant in the map sq
//   cx,xz   is the index of the collsion map the plant is in
//  x2,z2 is the location of the plant in the collision map
//  rad is the radius of the plant
//  for each plant in map, if in CM, add to CM
//  value is the value written to the CM
for (a=0; a<maxplants; a++)
    {
//  calc plant x z
    x=px*plantmapsize+plant2[a].x;
    z=pz*plantmapsize+plant2[a].z;
    if (waterinway(mx,mz,x,z))
        {
        continue;
        }
    if (storepit_in_way(mx,mz,x,z))
        {
        continue;
        }
//  calc CM index cx,cz
//  if its not in this CM, skip the plant
    cx=x/CM_SIZE;
    if (cx != CM[i].cx)
        {
        continue;
        }
    cz=z/CM_SIZE;
    if (cz != CM[i].cz)
        {
        continue;
        }
//  ok, plant is in CM index cx,cz
//  add it to the CM
//  calc x,z coords in the CM (x2,z2)
    x2=x-cx*CM_SIZE;
    z2=z-cz*CM_SIZE;
//  set radius
    rad=2;
//  set value. 4 = fruit tree
    value=4;
//  add it!
    add_to_CM(i,x2,z2,rad,value);
    }
}
 
 
 
 
 
 
 
 
 
 
 
void add_trees_to_CM(int i,int mx,int mz,int cx,int cz)
{
int px1,pz1,px2,pz2,px3,pz3;
//  px1 etc are begin and end of loops for plant maps
//  px3 pz3      loop counters
px1=cx*CM_SIZE/plantmapsize;
px2=(cx+1)*CM_SIZE/plantmapsize;
pz1=cz*CM_SIZE/plantmapsize;
pz2=(cz+1)*CM_SIZE/plantmapsize;
for (px3=px1; px3<=px2; px3++)
    {
    for (pz3=pz1; pz3<=pz2; pz3++)
        {
//  add plant map mx mz px3 pz3
add_tree_plantmap_to_CM(i,mx,mz,px3,pz3);
        }
    }
}
 
 
 
 
 
 
 
 
 
void add_savanna_trees_to_CM(int i,int mx,int mz,int cx,int cz)
{
int px1,pz1,px2,pz2,px3,pz3;
//  px1 etc are begin and end of loops for plant maps
//  px3 pz3      loop counters
px1=cx*CM_SIZE/plantmapsize;
px2=(cx+1)*CM_SIZE/plantmapsize;
pz1=cz*CM_SIZE/plantmapsize;
pz2=(cz+1)*CM_SIZE/plantmapsize;
for (px3=px1; px3<=px2; px3++)
    {
    for (pz3=pz1; pz3<=pz2; pz3++)
        {
add_savanna_tree_plantmap_to_CM(i,mx,mz,px3,pz3);
        }
    }
}
 
 
 
 
 
 
 
 
void add_rocks_to_CM(int i,int mx,int mz,int cx,int cz)
{
int px1,pz1,px2,pz2,px3,pz3;
//  px1 etc are begin and end of loops for plant maps
//  px3 pz3      loop counters
px1=cx*CM_SIZE/plantmapsize;
px2=(cx+1)*CM_SIZE/plantmapsize;
pz1=cz*CM_SIZE/plantmapsize;
pz2=(cz+1)*CM_SIZE/plantmapsize;
for (px3=px1; px3<=px2; px3++)
    {
    for (pz3=pz1; pz3<=pz2; pz3++)
        {
//  add plant map mx mz px3 pz3
add_rock_plantmap_to_CM(i,mx,mz,px3,pz3);
        }
    }
}
 
 
 
 
 
 
 
 
void add_fruittrees_to_CM(int i,int mx,int mz,int cx,int cz)
{
int px1,pz1,px2,pz2,px3,pz3;
//  px1 etc are begin and end of loops for plant maps
//  px3 pz3      loop counters
px1=cx*CM_SIZE/plantmapsize;
px2=(cx+1)*CM_SIZE/plantmapsize;
pz1=cz*CM_SIZE/plantmapsize;
pz2=(cz+1)*CM_SIZE/plantmapsize;
for (px3=px1; px3<=px2; px3++)
    {
    for (pz3=pz1; pz3<=pz2; pz3++)
        {
//  add plant map mx mz px3 pz3
add_fruittree_plantmap_to_CM(i,mx,mz,px3,pz3);
        }
    }
}
 
 
 
 
 
 
 
void add_caves_to_CM(int i,int mx,int mz,int cx,int cz)
{
int num,a,index,cx2,cz2,x,z;
num=numcaves[mx][mz];
if (num < 1)
    {
    return;
    }
for (a=0; a<num; a++)
    {
    index=caveindex[mx][mz][a];
//  calc CM index of the cave
    cx2=crh2[index].x/CM_SIZE;
    cz2=crh2[index].z/CM_SIZE;
//  if cave not in this CM, skip the cave
    if (cx2 != cx)
        {
        continue;
        }
    if (cz2 != cz)
        {
        continue;
        }
//  cave is in this CM.
//  calc caves CM xz coords
    x=crh2[index].x-cx*CM_SIZE;
    z=crh2[index].z-cz*CM_SIZE;
//  rad=24      value=2 (cave)
    add_to_CM(i,x,z,24,2);
    }
}
 
    
 
 
 
 
 
 
 
void add_cavern_to_CM(int i,int cx,int cz)
{
int x,z,cx2,cz2;
//   calc CM of cavern (cx2 cz2)
cx2=cavern_x/CM_SIZE;
cz2=cavern_z/CM_SIZE;
//  if cavern CM is not this CM, return
if (cx != cx2)
    {
    return;
    }
if (cz != cz2)
    {
    return;
    }
//  calc x,z of cavern
x=cavern_x-cx*CM_SIZE;
z=cavern_z-cz*CM_SIZE;
//  5 = cavern   rad=40
add_to_CM(i,x,z,40,5);
}
 
 
 
void add_rockshelters_to_CM(int i,int mx,int mz,int cx,int cz)
{
int a,cx2,cz2,x,z;
for (a=60000; a<65000; a++)
    {
//  skip if different map sq
if (crh2[a].mx != mx)
    {
    continue;
    }
//  skip if different map sq
if (crh2[a].mz != mz)
    {
    continue;
    }
//  calc CM index (cx2,cz2) of rockshelter
cx2=crh2[a].x/CM_SIZE;
cz2=crh2[a].z/CM_SIZE;
//  skip if not in this CM
if (cx2 != cx)
    {
    continue;
    }
if (cz2 != cz)
    {
    continue;
    }
//  ok its in this CM
//  calc ccords
x=crh2[a].x-cx*CM_SIZE;
z=crh2[a].z-cz*CM_SIZE;
//  rad = 30    6 = rockshelter
add_to_CM(i,x,z,30,6);
//  clear the interior
add_to_CM(i,x,z-10,20,0);
    }
}
 
 
 
 
 
 
 
void add_volcano_to_CM(int i,int cx,int cz)
{
int x,z,cx2,cz2;
//   calc CM of volcano (cx2 cz2)
cx2=volcano_x/CM_SIZE;
cz2=volcano_z/CM_SIZE;
//  if cavern CM is not this CM, return
if (cx != cx2)
    {
    return;
    }
if (cz != cz2)
    {
    return;
    }
//  calc x,z of volcano
x=volcano_x-cx*CM_SIZE;
z=volcano_z-cz*CM_SIZE;
//  6 = volcano   rad=50
add_to_CM(i,x,z,50,6);
}
 
 
 
 
 
 
 
 
 
 
 
 
 
void add_huts_to_CM(int i,int mx,int mz,int cx,int cz)
{
int num,a,b,cx2,cz2,x,z;
num=numhuts3[mx][mz];
if (num < 1)
    {
    return;
    }
for (a=0; a<num; a++)
    {
    b=hutindex3[mx][mz][a];
    cx2=crh2[b].x/CM_SIZE;
    cz2=crh2[b].z/CM_SIZE;
    if (cx != cx2)
        {
        continue;
        }
    if (cz != cz2)
        {
        continue;
        }
    x=crh2[b].x-cx*CM_SIZE;
    z=crh2[b].z-cz*CM_SIZE;
//  7 = hut
    add_to_CM(i,x,z,10,7);
    }
}
 
 
 
 
 
 
 
 
 
 
void add_permshelters_to_CM(int i,int mx,int mz,int cx,int cz)
{
int a,x,z,cx2,cz2;
for (a=0; a<maxcavemen; a++)
    {
    if (!cm[a].active)
        {
        continue;
        }
    if (!cm[a].alive)
        {
        continue;
        }
    if (!cm[a].has_perm_shelter)
        {
        continue;
        }
    if (cm[a].shel_mx != mx)
        {
        continue;
        }
    if (cm[a].shel_mz != mz)
        {
        continue;
        }
    cx2=cm[a].shel_x/CM_SIZE;
    cz2=cm[a].shel_z/CM_SIZE;
    if (cx != cx2)
        {
        continue;
        }
    if (cz != cz2)
        {
        continue;
        }
    x=cm[a].shel_x-cx*CM_SIZE;
    z=cm[a].shel_z-cz*CM_SIZE;
//  8 = perm shel
    add_to_CM(i,x,z,10,8);
    }
}
 
 
 
 
 
 
 
 
void add_tempshelters_to_CM(int i,int mx,int mz,int cx,int cz)
{
int a,cx2,cz2,x,z;
for (a=0; a<max_world_objects; a++)
    {
    if (!worldobj[a].active)
        {
        continue;
        }
    if (!isshelter(a))
        {
        continue;
        }
    if (worldobj[a].mx != mx)
        {
        continue;
        }
    if (worldobj[a].mz != mz)
        {
        continue;
        }
    cx2=(int)worldobj[a].x/CM_SIZE;
    cz2=(int)worldobj[a].z/CM_SIZE;
    if (cx != cx2)
        {
        continue;
        }
    if (cz != cz2)
        {
        continue;
        }
    x=(int)worldobj[a].x-cx*CM_SIZE;
    z=(int)worldobj[a].z-cz*CM_SIZE;
//  9 = temp shelter
    add_to_CM(i,x,z,5,9);
    }
}
 
 
 
 
 
 
 
 
 
 
void gen_CM(int i,int mx,int mz,int cx,int cz)
{
//  clear the collision map
clear_CM(i);
//  helps if you make it active, etc! also - cx,cz must be set to add plantmaps (trees, rocks, fruit trees)!
CM[i].active=1;
CM[i].mx=mx;
CM[i].mz=mz;
CM[i].cx=cx;
CM[i].cz=cz;
//  add trees as required...
switch (map[mx][mz].coverage)
    {
    case WOODS:
        case JUNGLE:
            add_trees_to_CM(i,mx,mz,cx,cz);
            break;
        case SAVANNA:
            add_savanna_trees_to_CM(i,mx,mz,cx,cz);
            break;
        }
    add_caves_to_CM(i,mx,mz,cx,cz);
    if (map[mx][mz].rocks)
        {
        add_rocks_to_CM(i,mx,mz,cx,cz);
        }
    if (map[mx][mz].fruittree)
        {
        add_fruittrees_to_CM(i,mx,mz,cx,cz);
        }
    if (map[mx][mz].cavern)
        {
        add_cavern_to_CM(i,cx,cz);
        }
    add_rockshelters_to_CM(i,mx,mz,cx,cz);
    if (map[mx][mz].volcano)
        {
        add_volcano_to_CM(i,cx,cz);
        }
    add_huts_to_CM(i,mx,mz,cx,cz);
    add_permshelters_to_CM(i,mx,mz,cx,cz);
    add_tempshelters_to_CM(i,mx,mz,cx,cz);
    }
 
 
 
 
 
 
 
 
 
 
 
int get_CM_index(int mx,int mz,int cx,int cz)
{
int best,bestval,a;
//  first: see if it exists, if so return its index...
for (a=0; a<CM_CACHE_SIZE; a++)
    {
    if (!CM[a].active)
        {
        continue;
        }
    if (CM[a].mx != mx)
        {
        continue;
        }
    if (CM[a].mz != mz)
        {
        continue;
        }
    if (CM[a].cx != cx)
        {
        continue;
        }
    if (CM[a].cz != cz)
        {
        continue;
        }
    return(a);
    }
//  doesnt exist. need to make one.
//  serch for inactive, if found, use it to generate a CM and return its index...
for (a=0; a<CM_CACHE_SIZE; a++)
    {
    if (!CM[a].active)
        {
        gen_CM(a,mx,mz,cx,cz);
        return(a);
        }
    }
//  didnt find inactive CM. must use LRU one.
//  find LRU CM, use it to gen new CM, and return its index...
best=0;
bestval=0;
for (a=0; a<CM_CACHE_SIZE; a++)
    {
    if (CM[a].age > bestval)
        {
        best=a;
        bestval=CM[a].age;
        }
    }
gen_CM(best,mx,mz,cx,cz);
return(best);
}
 
 
 
 
 
 
 
//  age all maps except map i
void age_CMs(int i)
{
int a;
for (a=0; a<CM_CACHE_SIZE; a++)
    {
    if (!CM[a].active)
        {
        continue;
        }
    if (a == i)
        {
        CM[a].age=0;
        }
    else
        {
        CM[a].age++;
        }
    }
}
 
 
 
 
 
 
 
 
 
 
int CM_terrain_in_way(int mx,int mz,int x,int z,int rad)
{
int x1,z1,x2,z2,a,b,a2,b2,mx2,mz2,cx,cz,a3,b3,i;
//  x1 z1 z2 z2      start and end of loops 
//  a b    loop counters
//   mx2 mz2 a2 b2      normalized world coords
//  mx2 mz2 cx cz a3 b3     collsion map coords
//  i is the index of the collsion map
//  check for "off the map"
if (mx < 0)
    {
    return(1);
    }
if (mx >= mapsize)
    {
    return(1);
    }
if (mz < 0)
    {
    return(1);
    }
if (mz >= mapsize)
    {
    return(1);
    }
if (map[mx][mz].elevation == OCEAN)
    {
    return(1);
    }
if (map[mx][mz].elevation == IMPASSMTNS)
    {
    return(1);
    }
x1=x-rad;
z1=z-rad;
x2=x+rad;
z2=z+rad;
for (a=x1; a<=x2; a++)
    {
    for (b=z1; b<=z2; b++)
        {
mx2=mx;
mz2=mz;
a2=a;
b2=b;
//  normalize mx2 mz2 a2 b2
while (a2<0)
    {
    a2+=map_sq_size;
    mx2--;
    }
while (a2>=map_sq_size)
    {
    a2-=map_sq_size;
    mx2++;
    }
while (b2<0)
    {
    b2+=map_sq_size;
    mz2--;
    }
while (b2>=map_sq_size)
    {
    b2-=map_sq_size;
    mz2++;
    }
//  if off edge of world map, return -1    
if (mx2 < 0)
    {
    return(-1);
    }
if (mx2 >= mapsize)
    {
    return(-1);
    }
if (mz2 < 0)
    {
    return(-1);
    }
if (mz2 >= mapsize)
    {
    return(-1);
    }
//  convert to CM coords: mx2 mz2 cx cz a3 b3
cx=a2/CM_SIZE;
cz=b2/CM_SIZE;
a3=a2-cx*CM_SIZE;
b3=b2-cz*CM_SIZE;
//  get index of collsion map mx2 mz2 cx cz
i=get_CM_index(mx2,mz2,cx,cz);
age_CMs(i);
//  if cm[i].data[a3][b3] !=0, ret cm[i].data[a3][b3]
if (CM[i].data[a3][b3] != 0)
    {
    return(CM[i].data[a3][b3]);
    }
        }
    }
return(0);
}
 
 
 
 
 
 
 
 
//  ############################### END COLLISION MAPS ################################################
 
 

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement

continuing from previous post (mixing text and code doesn't work well for me for some reason).....

so the oo way:

a collision map struct + the methods that operate on a single struct would become a class. and the array of collision maps and the methods that operate on the array would become a second class.

but then i have a list of object pointers... not an array of structs...

so the entire array of structs and all the methods become a single class?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


but then i have a list of object pointers... not an array of structs...

I don't understand. What does this have to do with making your code more object-oriented?

I would do it piece by piece. For example, change CMrec to use the class keyword, but start out with everything public. Then maybe make clear_CM_cache call a clear() method on each element in CM instead of calling clear_CM for each index. As you move code into CMrec, you won't need every member to be public, so you can start making things private. Eventually, you'll have the syntax you want.


I don't understand. What does this have to do with making your code more object-oriented?

it adds an extra dereference, so its not "exactly the same thing - but using oo syntax".

its more like an array of pointers to structs, than an array of structs.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

You don't need to put structs inside classes, the class itself serves as a place to group all the fields.


class CollisionMap {
  private: // or public, you should check each attribute
    int active,age,mx,mz,cx,cz,data[CM_SIZE][CM_SIZE];

  public:
    void add_tree_plantmap(int i,int mx,int mz,int px,int pz);
    // more public methods

  private:
    void add(int i,int x,int z,int rad,int value);
    // more private methods
}

If you have methods that work over a list of collision maps and those can't be placed somewhere else, it makes sense to create a class that is actually a list of collision maps, but it's highly tied to how you design your solution. There's not a single rule to follow, you'll know if it makes sense to create a class for something with some experience.

In this case, if you only have one method you could write:


class CollisionMapsList {
  private:
    std::vector<CollisionMap> maps;

  public:
    void age(int i);
}

or (if you want to still treat it like a vector a have a vector interface):


class CollisionMapsList : public std::vector<CollisionMap> {
  public:
    void age(int i);
}

But it looks like the vector of collision maps and the "age" method could be inside a bigger class (maybe inside a class "Field"? or "Level"?).

EDIT: Also, you should check all the parameters you use and your naming convention, it's really hard to understand what your code is doing.

"OO" is not a syntax. It is a specific way of organizing your programs.

I can't follow your code to save my life (see DieogSLTS's comment) but it seems to me like you need fundamentally more change to your program than just rearranging some squiggly symbols and calling it OO.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

What ApochPiQ said; you need to oop your design, not your syntax. What you're doing isn't so much of a port as a re-design. I don't mean to "be mean", but I'm gonna come off as such here: but do you really work for a pc gaming shop as in your tag line? I think back to all the places I put my resume in at and all the rejections I got due to some niggling corner of the c97 specification I missed and I gotta wonder how you got in with a game producer...

but then i have a list of object pointers... not an array of structs...


Why? You can have an array of class _values_. This is perfectly legal:

class MyComplexClass { ... };

MyComplexClass array[100];
std::vector<MyComplexClass> vector;
OO as taught by Java schools (which have infected most C++ programmers, sadly) will indeed teach you to make a bunch of little objects with overly-specific functionality independent of larger systems. This is wrong. You can have a class that internally uses an array or vector to arrange its data. Both of the following are valid OO structures (in totally not-valid syntax), but one is fast and one is idiotic:

// Java-esque:
class Object {
  GetName();
  GetSize();
  DoStuff();
};

class ObjectManager {
  list of Object

  Object& GetObject(key);
};
// Better:
class ObjectManager {
  struct ObjectData {
    name;
    size;
    etc;
  };

  list of ObjectData;

  GetSize(Key);
  GetName(Key);
  DoStuffAll() { for each object: do stuff; }
}

Sean Middleditch – Game Systems Engineer – Join my team!

At minimum the sizing/placement code that appears repeatedly could be crushed down to a parent class object method.

Look for other common operations to be shared/inheritted

--------------------------------------------[size="1"]Ratings are Opinion, not Fact

OO as taught by Java schools (which have infected most C++ programmers, sadly) will indeed teach you to make a bunch of little objects with overly-specific functionality independent of larger systems. This is wrong. You can have a class that internally uses an array or vector to arrange its data. Both of the following are valid OO structures (in totally not-valid syntax), but one is fast and one is idiotic:


That's a little harsh.

OO as embodied by the original intent of the concept looks more like your first example than the second. The second one is more illustrative of Data Oriented Architecture which is a totally different beast again from OO.

Please don't conflate "different" with "one has to be wrong."

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement