comparison src/graphics.cc @ 8234:8c4e79668a5e

generate new fractional parts for recycled graphics handles
author John W. Eaton <jwe@octave.org>
date Thu, 16 Oct 2008 17:07:02 -0400
parents beaf723a49eb
children 1f429086565c
comparison
equal deleted inserted replaced
8233:beaf723a49eb 8234:8c4e79668a5e
1241 } 1241 }
1242 else 1242 else
1243 error ("set: invalid number of arguments"); 1243 error ("set: invalid number of arguments");
1244 } 1244 }
1245 1245
1246 static double
1247 make_handle_fraction (void)
1248 {
1249 static double maxrand = RAND_MAX + 2.0;
1250
1251 return (rand () + 1.0) / maxrand;
1252 }
1246 1253
1247 graphics_handle 1254 graphics_handle
1248 gh_manager::get_handle (const std::string& go_name) 1255 gh_manager::get_handle (const std::string& go_name)
1249 { 1256 {
1250 graphics_handle retval; 1257 graphics_handle retval;
1251 1258
1252 if (go_name == "figure") 1259 if (go_name == "figure")
1253 { 1260 {
1261 // Figure handles are positive integers corresponding to the
1262 // figure number.
1263
1254 // We always want the lowest unused figure number. 1264 // We always want the lowest unused figure number.
1255 1265
1256 retval = 1; 1266 retval = 1;
1257 1267
1258 while (handle_map.find (retval) != handle_map.end ()) 1268 while (handle_map.find (retval) != handle_map.end ())
1259 retval++; 1269 retval++;
1260 } 1270 }
1261 else 1271 else
1262 { 1272 {
1273 // Other graphics handles are negative integers plus some random
1274 // fractional part. To avoid running out of integers, we
1275 // recycle the integer part but tack on a new random part each
1276 // time.
1277
1263 free_list_iterator p = handle_free_list.begin (); 1278 free_list_iterator p = handle_free_list.begin ();
1264 1279
1265 if (p != handle_free_list.end ()) 1280 if (p != handle_free_list.end ())
1266 { 1281 {
1267 retval = *p; 1282 retval = *p;
1268 handle_free_list.erase (p); 1283 handle_free_list.erase (p);
1269 } 1284 }
1270 else 1285 else
1271 { 1286 {
1272 static double maxrand = RAND_MAX + 2.0;
1273
1274 retval = graphics_handle (next_handle); 1287 retval = graphics_handle (next_handle);
1275 1288
1276 next_handle = ceil (next_handle) - 1.0 - (rand () + 1.0) / maxrand; 1289 next_handle = ceil (next_handle) - 1.0 - make_handle_fraction ();
1277 } 1290 }
1278 } 1291 }
1279 1292
1280 return retval; 1293 return retval;
1281 } 1294 }
1308 1321
1309 // Note: this will be valid only for first explicitly 1322 // Note: this will be valid only for first explicitly
1310 // deleted object. All its children will then have an 1323 // deleted object. All its children will then have an
1311 // unknown backend. 1324 // unknown backend.
1312 1325
1326 // Graphics handles for non-figure objects are negative
1327 // integers plus some random fractional part. To avoid
1328 // running out of integers, we recycle the integer part
1329 // but tack on a new random part each time.
1330
1313 handle_map.erase (p); 1331 handle_map.erase (p);
1314 1332
1315 if (h.value () < 0) 1333 if (h.value () < 0)
1316 handle_free_list.insert (h); 1334 handle_free_list.insert (ceil (h.value ()) - make_handle_fraction ());
1317 } 1335 }
1318 else 1336 else
1319 error ("graphics_handle::free: invalid object %g", h.value ()); 1337 error ("graphics_handle::free: invalid object %g", h.value ());
1320 } 1338 }
1321 else 1339 else