Main Index : Reference :

VariableChanged


Description

A variable changed class.

Definition

class VariableChanged
{
public:
  VariableChanged();

  [bool] Init([int] old_count, [int] new_count, [[array] map]);

  [array] GetMap();

  [int] GetOldCount();
  [int] GetNewCount();
}

Explanation

This structure is essential for changing point/polygon counts in objects cause one can allocated or remove multiple elements with a single Message call. It can be used for example when sending MSG_POINTS_CHANGED and MSG_POLYGONS_CHANGED messages to objects, tags and keys.

The structure contains the number of elements (points or polygons) before and after the change, and optionally a translation map array. Each element in the map represents an element before the change, and its value decides what element this corresponds to after the change. This is used to keep for example point selections and vertex maps valid.

Important: Make sure that you use a BackupTags object as well when changing for example the point size of an object. Otherwise the object might be corrupted in low-memory situations.

Members

Init( old_count, new_count, [map] )

[bool] Init([int] old_count, [int] new_count, [[array] map]);

Clears all internal variables and sets up the structure to represent a change from old_count to new_count elements, optionally using the translation table map.

GetMap()

[array] GetMap();

Returns the map.


GetOldCount()

[int] GetOldCount();

Returns the old number of elements.

GetNewCount()

[int] GetNewCount();

Returns the new number of elements.

Example

Please also see the example for BackupTags. This applies to all the three examples!


Example 1: Adding a point to a point object.

if (!instanceof(op,PointObject)) return FALSE;        // Not a point object.
var vc = new(VariableChanged); if (!vc) return FALSE; // Allocate class.

var cnt = op->GetPointCount();  // Get actual point count.
vc->Init(cnt,cnt+1);            // Resize point count from cnt to cnt+1.
                                // Just for adding a point at the end of 
																// the point list one doesn't need a map.
																
// Send the message to all tags and keys and let them return 
// a boolean, telling us if everything is alright:
																
var ok = op->MultiMessage(MSG_POINTS_CHANGED,vc); 

// Now all tags and structures have reacted and resized their 
// memory part, so one can access the new point:

op->SetPoint(cnt, p);    // Set data p for new point
op->Message(MSG_UPDATE); // Notify object of change


Example 2: Inserting a point at position pos.

if (!instanceof(op,PointObject)) return FALSE;        // Not a point object.
var vc = new(VariableChanged); if (!vc) return FALSE; // Allocate class.

var cnt = op->GetPointCount(); if (!cnt) return TRUE; // Get actual point count.

// Allocate mapping table.
var i, map = new(array, cnt); if (!map) return FALSE;

// The points below pos stay at the same point number:
for (i=0; i<=pos; i++)
  map[i] = i;

// The points above pos are shifted 1 step:
for (i=pos+1; i<cnt; i++)
  map[i] = i + 1;

vc->Init(cnt,cnt+1,map); // Resize point count from cnt to cnt+1 and send mapping table.

// Now all tags and structures have reacted and resized their 
// memory part, so one can access the new point:

op->SetPoint(pos, p);    // Set data p for new point
op->Message(MSG_UPDATE); // Notify object of change


Example3: // wanna reverse the point order?

if (!instanceof(op,PointObject)) return FALSE;        // Not a point object.
var vc = new(VariableChanged); if (!vc) return FALSE; // Allocate class.

var cnt = op->GetPointCount(); if (!cnt) return TRUE; // Get actual point count.

// Allocate mapping table:
var i, map = new(array, cnt); if (!map) return FALSE;

// Reverse point numbers:
for (i=0; i<cnt; i++)
  map[i] = cnt-i-1;

vc->Init(cnt,cnt,map); // Send mapping table, no resizing.

// Send the message to all tags and keys:
op->MultiMessage(MSG_POINTS_CHANGED,vc);