0

Some question about ability of writing hybrid getters/setters... For my chess app I have an object diagram much more similar to a graph than a tree. So I decide to pool the various kind of objects in a data structure holding both object instances and relations between them.

Something like:

// in js/app/base/pools.js
var Pool = function() {
    this.items = {};
    this.relations = {};
};

/**
 * store an object into the pool
 * and augment it with relation/pooling capabilities
 * @param string key
 * @param Object obj
 */
 Pool.prototype.store = function(key, obj) {
    
    var self = this;

    Object.defineProperty(obj.constructor.prototype, "pool", {
        set : undefined,
        get : function() {
            return self;
        }
    });

    this.items[key] = obj;
 };

 /**
  * looks for an object in the pool
  * @param string
  */
 Pool.prototype.find = function(key) {
    return this.items[key];
 };

Relations are stored as pairs [obj1, obj2] in the "relations" property of the Pool instance. I have basically two kinds of relationship:

  • One-to-one: unary correspondences like Chessman <--> Location, or interface implementation like Chessman <--> Pawn | ... | King

  • One-to-many like Board [x1] <--> [x64] Tile

Those relations are designed (by the pool way) to be bi-directional and have to be set atomically (e.g. transactions) since object cross-references need to be "ACID", for the above example, 1 Board contain 64 Tiles, and each tile knows about its standing board.

For 1-to-1 relations, maybe no problem, since I can set:

chessman.location = location;
// AND AT THE SAME TIME :
location.chessman = chessman;

// with two Object.defineProperty(...) combined

The trouble comes with 1-N relations since I would be able to write:

// 1st : defining relation
// ... (see below)

// 2nd setting a relation
board1.tiles.add(tile_63);
// and
tile_63.board = board1;

// 3rd getting values
board1.tiles --> a collection of tiles (array)
tile_63.board --> board1 object

In the main program the relation is given to the Pool instance by passing a parameter object:

pool.defineRelation("board-contains-tiles", {
    tiles : { subject : boards.Board, multiple : true },
    board : { subject : tiles.Tile, multiple : false }
});

To define the relation, 1-side is a normal getter/setter, but N-side is more a getter-adder since we have to populate (the board with tiles). So this doesn't work:

 Pool.prototype.defineRelation = function(alias, definition) {
    this.relations[alias] = [];

    var self = this, linker;
    var relation = self.relations[alias];
    var subject, multiple;

    // iterate through relation short names
    for(name in definition) {
        
        subject = definition[name].subject;
        multiple = definition[name].multiple;

        console.log("loop with name : " + name + " subject is : " + subject);

        var getter =  function() {
                var result = [];
                for(r = 0; r < relation.length; r++) {
                    
                    // [x,y] storing
                    if(relation[r][0] == this) 
                        result.push( relation[r][1]);
                    
                    // [y,x] storing
                    if(relation[r][1] == this) 
                        result.push( relation[r][0]);

                    return result;

                };

        var setter;

        if(multiple) {
            setter = function() {};
            setter.add = function(x) { relation.push([this, x]); };
        } else {
            setter = function(x) { relation.push([this, x]); };
        }

        Object.defineProperty(subject.prototype, name, {
            set : setter,
            get : getter
        }); 

    }
};

Question: I'm figuring it's possible to do that, but how? Or in a better way, like Delphi's TComponent, or like the DOM tree?

SEE ALSO: The old, ugly, and messy codebase can be found on my website:

www.eozine.fr --> Jet d'echecs --> ColorChess

If you want to see a previous result (2009)

VLAZ
  • 26,331
  • 9
  • 49
  • 67
  • A possible way to solution : object breeding (type objects) http://gameprogrammingpatterns.com/type-object.html – Hefeust CORTES Oct 24 '13 at 18:35
  • it s a trick... I wish it is a solvable problem... – Hefeust CORTES Nov 01 '13 at 20:45
  • Don't do `Object.defineProperty(obj.constructor.prototype, …)` - that will affect the entire class of `obj` for any `obj` you choose to store in your pool. And it will be very inefficient to redefine this getter every time you store an object. – Bergi Dec 31 '22 at 17:24

0 Answers0