<commit_before>'use strict';

var _ = require('lodash'),
    EventEmitter = require('events').EventEmitter,
    Promise = require('bluebird'),
    util = require('util'),

    StateMachine = require('stately.js'),

    debug = require('debug')('amqp10:link'),

    constants = require('./constants'),
    errors = require('./errors'),

    AttachFrame = require('./frames/attach_frame'),
    DetachFrame = require('./frames/detach_frame'),
    FlowFrame = require('./frames/flow_frame'),
    TransferFrame = require('./frames/transfer_frame'),
    DispositionFrame = require('./frames/disposition_frame'),

    DeliveryStates = require('./types/delivery_states'),
    Session = require('./session');

function Link(session, handle, linkPolicy) {
  this.policy = linkPolicy;
  this.session = session;
  this.handle = handle;
  this.attached = false;
  this.remoteHandle = undefined;

  var self = this;
  var stateMachine = {
    'DETACHED': {
      sendAttach: function() {
        return this.ATTACHING;
      }
    },
    'ATTACHING': {
      attachReceived: function() {
        return this.ATTACHED;
      }
    },
    'ATTACHED': {
      sendDetach: function() {
        return this.DETACHING;
      },
      detachReceived: function() {
        self._sendDetach();
        return this.DETACHING;
      }
    },
    'DETACHING': {
      detachReceived: function() {
        return this.DETACHED;
      },
      detached: function() {
        return this.DETACHED;
      }
    }
  };

  this.linkSM = new StateMachine(stateMachine).bind(function(event, oldState, newState) {
    debug('Transitioning from ' + oldState + ' to ' + newState + ' due to ' + event);
  });
}

util.inherits(Link, EventEmitter);

// On receipt of a message.  Message payload given as argument.
Link.MessageReceived = 'link:messageReceived';

// Since 'error' events are "special" in Node (as in halt-the-process special),
// using a custom event for errors we receive from the other endpoint. Provides
// received AMQPError as an argument.
Link.ErrorReceived = 'link:errorReceived';

// On link credit changed.
Link.CreditChange = 'link:creditChange';

// On completion of detach.
Link.Detached = 'link:detached';

// public api
Link.prototype.attach = function() {
  this.linkSM.sendAttach();
  var attachFrame = new AttachFrame(this.policy.options);
  attachFrame.channel = this.session.channel;
  debug('Tx attach CH=' + attachFrame.channel + ', Handle=' + attachFrame.handle);
  if (attachFrame.role === constants.linkRole.sender) {
    this.initialDeliveryCount = attachFrame.initialDeliveryCount;
    this.deliveryCount = attachFrame.deliveryCount;
  }

  this.name = attachFrame.name;
  this.role = attachFrame.role;
  this.linkCredit = 0;
  this.totalCredits = 0;
  this.available = 0;
  this.drain = false;
  this.session.connection.sendFrame(attachFrame);
};

Link.prototype.detach = function() {
  var self = this;
  var detachPromise = new Promise(function(resolve, reject) {
    var onError = function(err) { reject(err); };
    self.once(Link.ErrorReceived, onError);
    self.once(Link.Detached, function(info) {
      self.removeListener(Link.ErrorReceived, onError);
      if (!!info.error) return reject(info.error);
      if (!info.closed) return reject('link not closed');
      resolve();
    });
  });

  this.linkSM.sendDetach();
  this._sendDetach();
  return detachPromise;
};

Link.prototype.isSender = function() { return this.role === constants.linkRole.sender; };

Link.prototype.canSend = function() {
  var sendable = (this.linkCredit >= 1 && (!this.session.policy.enableSessionFlowControl || this.session._sessionParams.remoteIncomingWindow >= 1));
  debug('canSend(' + this.linkCredit + ',' + this.session._sessionParams.remoteIncomingWindow + ') = ' + sendable);
  return sendable;
};

Link.prototype.sendMessage = function(message, options) {
  return this.session.sendMessage(this, message, options);
};

Link.prototype.addCredits = function(credits, flowOptions) {
  if (this.role === constants.linkRole.sender) {
    throw new errors.InvalidStateError('Cannot add link credits as a sender');
  }

  var opts = flowOptions || {};
  this.linkCredit += credits;
  this.totalCredits += credits;
  opts.linkCredit = this.totalCredits;
  this.session._sessionParams.incomingWindow += credits;
  opts.nextIncomingId = this.session._sessionParams.nextIncomingId;
  opts.incomingWindow = this.session._sessionParams.incomingWindow;
  opts.nextOutgoingId = this.session._sessionParams.nextOutgoingId;
  opts.outgoingWindow = this.session._sessionParams.outgoingWindow;
  opts.handle = this.handle;
  opts.available = this.available;
  opts.deliveryCount = this.deliveryCount;
  opts.drain = false;
  var flow = new FlowFrame(opts);
  flow.channel = this.session.channel;
  this.session.connection.sendFrame(flow);

  var self = this;
  return new Promise(function(resolve, reject) {
    var onError = function(err) { reject(err); };
    self.once(Link.ErrorReceived, onError);
    self.once(Link.CreditChange, function() {
      self.removeListener(Link.ErrorReceived, onError);
      resolve();
    });
  });
};

Link.prototype.accept = function(message) {
  // @todo: handle accepting an array of messages
  this._sendDisposition({
    first: message._deliveryId,
    last: message._deliveryId,
    settled: true,
    state: new DeliveryStates.Accepted()
  });
};

Link.prototype.reject = function(message, reason) {
  // @todo: handle accepting an array of messages
  this._sendDisposition({
    first: message._deliveryId,
    last: message._deliveryId,
    settled: true,
    state: new DeliveryStates.Rejected({ error: reason })
  });
};

// private api
Link.prototype._attachReceived = function(attachFrame) {
  this.linkSM.attachReceived();
  // process params.
  this.remoteHandle = attachFrame.handle;
  this.session._linksByRemoteHandle[this.remoteHandle] = this;
  if (this.role === constants.linkRole.receiver) {
    this.deliveryCount = attachFrame.deliveryCount;
  }
  debug('Rx attach CH=[' + this.session.channel + '=>' + attachFrame.channel + '], Handle=[' + this.handle + '=>' + attachFrame.handle + ']');
  this.attached = true;

  // @todo: Session should listen for Link.Attached
  this.session._linkAttached(this);

  this._checkCredit();
};

Link.prototype._flowReceived = function(flowFrame) {
  if (this.role === constants.linkRole.sender) {
    if (flowFrame.handle !== null) {
      this.available = flowFrame.available;
      this.deliveryCount = flowFrame.deliveryCount;
      this.linkCredit = flowFrame.linkCredit;
      this.totalCredits += flowFrame.linkCredit;
      debug('Setting Credits (' + this.linkCredit + ',' + this.session._sessionParams.remoteIncomingWindow + ')');
    }
    this.emit(Link.CreditChange, this);
  } else {
    this.drain = flowFrame.drain;
  }
};

Link.prototype._checkCredit = function() {
  if (this.role === constants.linkRole.receiver) {
    if (this.policy.credit && typeof this.policy.credit === 'function') {
      this.policy.credit(this);
    }
  }
};

Link.prototype._messageReceived = function(transferFrame) {
  this.linkCredit--;
  debug('Rx message ' + transferFrame.deliveryId + ' on ' + this.name + ', ' + this.linkCredit + ' credit, ' + this.session._sessionParams.incomingWindow + ' window left.');
  // @todo Bump link credit based on strategy
  this.emit(Link.MessageReceived, transferFrame.message);
  this._checkCredit();
};

Link.prototype._sendMessage = function(messageId, message, transferOptions) {
  if (this.linkCredit <= 0) {
    throw new errors.OverCapacityError('Cannot send if no link credit.');
  }
  var opts = transferOptions || {};
  opts.handle = this.handle;
  opts.deliveryId = messageId;
  opts.settled = this.session._sessionParams.senderSettleMode === constants.senderSettleMode.settled;
  var transferFrame = new TransferFrame(opts);
  transferFrame.channel = this.session.channel;
  transferFrame.message = message;
  this.linkCredit--;
  this.session.connection.sendFrame(transferFrame);
  return messageId;
};

Link.prototype._detachReceived = function(frame) {
  this.linkSM.detachReceived();
  if (this.linkSM.getMachineState() === 'DETACHING') this.linkSM.detached();
  this._detached(frame);
};

Link.prototype._sendDetach = function() {
  var detachFrame = new DetachFrame(this.policy.options);
  detachFrame.channel = this.session.channel;
  detachFrame.closed = true;
  this.session.connection.sendFrame(detachFrame);
};

Link.prototype._detached = function(frame) {
  if (frame && frame.error) {
    this.emit(Link.ErrorReceived, frame.error);
  }

  if (this.remoteHandle !== undefined) {
    this.session._linksByRemoteHandle[this.remoteHandle] = undefined;
    this.remoteHandle = undefined;
  }

  this.session._linksByName[this.policy.options.name] = undefined;
  this.session._allocatedHandles[this.policy.options.handle] = undefined;
  this.attached = false;
  this.emit(Link.Detached, { closed: frame.closed, error: frame.error });

  // @todo: Session should listen for Link.Detached
  this.session._linkDetached(this);
};

Link.prototype._sendDisposition = function(options) {
  var dispositionOptions = _.defaults(options, {
    role: constants.linkRole.receiver,
    channel: this.session.channel,
    handle: this.handle
  });

  this.session.connection.sendFrame(
    new DispositionFrame(dispositionOptions)
  );
};

module.exports = Link;
<commit_msg>feat(auto-settle): send disposition frames for auto-settle<commit_after>'use strict';

var _ = require('lodash'),
    EventEmitter = require('events').EventEmitter,
    Promise = require('bluebird'),
    util = require('util'),

    StateMachine = require('stately.js'),

    debug = require('debug')('amqp10:link'),

    constants = require('./constants'),
    errors = require('./errors'),
    u = require('./utilities'),

    AttachFrame = require('./frames/attach_frame'),
    DetachFrame = require('./frames/detach_frame'),
    FlowFrame = require('./frames/flow_frame'),
    TransferFrame = require('./frames/transfer_frame'),
    DispositionFrame = require('./frames/disposition_frame'),

    DeliveryState = require('./types/delivery_state'),
    Session = require('./session');

function Link(session, handle, linkPolicy) {
  this.policy = linkPolicy;
  this.session = session;
  this.handle = handle;
  this.attached = false;
  this.remoteHandle = undefined;

  var self = this;
  var stateMachine = {
    'DETACHED': {
      sendAttach: function() {
        return this.ATTACHING;
      }
    },
    'ATTACHING': {
      attachReceived: function() {
        return this.ATTACHED;
      }
    },
    'ATTACHED': {
      sendDetach: function() {
        return this.DETACHING;
      },
      detachReceived: function() {
        self._sendDetach();
        return this.DETACHING;
      }
    },
    'DETACHING': {
      detachReceived: function() {
        return this.DETACHED;
      },
      detached: function() {
        return this.DETACHED;
      }
    }
  };

  this.linkSM = new StateMachine(stateMachine).bind(function(event, oldState, newState) {
    debug('Transitioning from ' + oldState + ' to ' + newState + ' due to ' + event);
  });
}

util.inherits(Link, EventEmitter);

// On receipt of a message.  Message payload given as argument.
Link.MessageReceived = 'link:messageReceived';

// Since 'error' events are "special" in Node (as in halt-the-process special),
// using a custom event for errors we receive from the other endpoint. Provides
// received AMQPError as an argument.
Link.ErrorReceived = 'link:errorReceived';

// On link credit changed.
Link.CreditChange = 'link:creditChange';

// On completion of detach.
Link.Detached = 'link:detached';

// public api
Link.prototype.attach = function() {
  this.linkSM.sendAttach();
  var attachFrame = new AttachFrame(this.policy.options);
  attachFrame.channel = this.session.channel;
  debug('Tx attach CH=' + attachFrame.channel + ', Handle=' + attachFrame.handle);
  if (attachFrame.role === constants.linkRole.sender) {
    this.initialDeliveryCount = attachFrame.initialDeliveryCount;
    this.deliveryCount = attachFrame.deliveryCount;
  }

  this.name = attachFrame.name;
  this.role = attachFrame.role;
  this.linkCredit = 0;
  this.totalCredits = 0;
  this.available = 0;
  this.drain = false;
  this.session.connection.sendFrame(attachFrame);
};

Link.prototype.detach = function() {
  var self = this;
  var detachPromise = new Promise(function(resolve, reject) {
    var onError = function(err) { reject(err); };
    self.once(Link.ErrorReceived, onError);
    self.once(Link.Detached, function(info) {
      self.removeListener(Link.ErrorReceived, onError);
      if (!!info.error) return reject(info.error);
      if (!info.closed) return reject('link not closed');
      resolve();
    });
  });

  this.linkSM.sendDetach();
  this._sendDetach();
  return detachPromise;
};

Link.prototype.isSender = function() { return this.role === constants.linkRole.sender; };

Link.prototype.canSend = function() {
  var sendable = (this.linkCredit >= 1 && (!this.session.policy.enableSessionFlowControl || this.session._sessionParams.remoteIncomingWindow >= 1));
  debug('canSend(' + this.linkCredit + ',' + this.session._sessionParams.remoteIncomingWindow + ') = ' + sendable);
  return sendable;
};

Link.prototype.sendMessage = function(message, options) {
  return this.session.sendMessage(this, message, options);
};

Link.prototype.addCredits = function(credits, flowOptions) {
  if (this.role === constants.linkRole.sender) {
    throw new errors.InvalidStateError('Cannot add link credits as a sender');
  }

  var opts = flowOptions || {};
  this.linkCredit += credits;
  this.totalCredits += credits;
  opts.linkCredit = this.totalCredits;
  this.session._sessionParams.incomingWindow += credits;
  opts.nextIncomingId = this.session._sessionParams.nextIncomingId;
  opts.incomingWindow = this.session._sessionParams.incomingWindow;
  opts.nextOutgoingId = this.session._sessionParams.nextOutgoingId;
  opts.outgoingWindow = this.session._sessionParams.outgoingWindow;
  opts.handle = this.handle;
  opts.available = this.available;
  opts.deliveryCount = this.deliveryCount;
  opts.drain = false;
  var flow = new FlowFrame(opts);
  flow.channel = this.session.channel;
  this.session.connection.sendFrame(flow);

  var self = this;
  return new Promise(function(resolve, reject) {
    var onError = function(err) { reject(err); };
    self.once(Link.ErrorReceived, onError);
    self.once(Link.CreditChange, function() {
      self.removeListener(Link.ErrorReceived, onError);
      resolve();
    });
  });
};

Link.prototype.accept = function(message) {
  var range = u.dispositionRange(message);
  this._sendDisposition(_.defaults(range, {
    settled: true,
    state: new DeliveryState.Accepted()
  }));
};

Link.prototype.reject = function(message, reason) {
  var range = u.dispositionRange(message);
  this._sendDisposition(_.defaults(range, {
    settled: true,
    state: new DeliveryState.Rejected({ error: reason })
  }));
};

// private api
Link.prototype._attachReceived = function(attachFrame) {
  this.linkSM.attachReceived();
  // process params.
  this.remoteHandle = attachFrame.handle;
  this.session._linksByRemoteHandle[this.remoteHandle] = this;
  if (this.role === constants.linkRole.receiver) {
    this.deliveryCount = attachFrame.deliveryCount;
  }
  debug('Rx attach CH=[' + this.session.channel + '=>' + attachFrame.channel + '], Handle=[' + this.handle + '=>' + attachFrame.handle + ']');
  this.attached = true;

  // @todo: Session should listen for Link.Attached
  this.session._linkAttached(this);

  this._checkCredit();
};

Link.prototype._flowReceived = function(flowFrame) {
  if (this.role === constants.linkRole.sender) {
    if (flowFrame.handle !== null) {
      this.available = flowFrame.available;
      this.deliveryCount = flowFrame.deliveryCount;
      this.linkCredit = flowFrame.linkCredit;
      this.totalCredits += flowFrame.linkCredit;
      debug('Setting Credits (' + this.linkCredit + ',' + this.session._sessionParams.remoteIncomingWindow + ')');
    }
    this.emit(Link.CreditChange, this);
  } else {
    this.drain = flowFrame.drain;
  }
};

Link.prototype._checkCredit = function() {
  if (this.role === constants.linkRole.receiver) {
    if (this.policy.credit && typeof this.policy.credit === 'function') {
      this.policy.credit(this);
    }
  }
};

Link.prototype._messageReceived = function(transferFrame) {
  this.linkCredit--;
  debug('Rx message ' + transferFrame.deliveryId + ' on ' + this.name + ', ' + this.linkCredit + ' credit, ' + this.session._sessionParams.incomingWindow + ' window left.');
  // @todo Bump link credit based on strategy

  // store deliveryId for later use
  transferFrame.message._deliveryId = transferFrame.deliveryId;

  // respect settle mode in policy
  if (this.policy.options.receiverSettleMode === constants.receiverSettleMode.autoSettle)
    this.accept(transferFrame.message);

  this.emit(Link.MessageReceived, transferFrame.message);
  this._checkCredit();
};

Link.prototype._sendMessage = function(messageId, message, transferOptions) {
  if (this.linkCredit <= 0) {
    throw new errors.OverCapacityError('Cannot send if no link credit.');
  }

  var opts = transferOptions || {};
  opts.handle = this.handle;
  opts.deliveryId = messageId;
  opts.settled = this.session._sessionParams.senderSettleMode === constants.senderSettleMode.settled;
  var transferFrame = new TransferFrame(opts);
  transferFrame.channel = this.session.channel;
  transferFrame.message = message;
  this.linkCredit--;
  this.session.connection.sendFrame(transferFrame);
  return messageId;
};

Link.prototype._detachReceived = function(frame) {
  this.linkSM.detachReceived();
  if (this.linkSM.getMachineState() === 'DETACHING') this.linkSM.detached();
  this._detached(frame);
};

Link.prototype._sendDetach = function() {
  var detachFrame = new DetachFrame(this.policy.options);
  detachFrame.channel = this.session.channel;
  detachFrame.closed = true;
  this.session.connection.sendFrame(detachFrame);
};

Link.prototype._detached = function(frame) {
  if (frame && frame.error) {
    this.emit(Link.ErrorReceived, frame.error);
  }

  if (this.remoteHandle !== undefined) {
    this.session._linksByRemoteHandle[this.remoteHandle] = undefined;
    this.remoteHandle = undefined;
  }

  this.session._linksByName[this.policy.options.name] = undefined;
  this.session._allocatedHandles[this.policy.options.handle] = undefined;
  this.attached = false;
  this.emit(Link.Detached, { closed: frame.closed, error: frame.error });

  // @todo: Session should listen for Link.Detached
  this.session._linkDetached(this);
};

Link.prototype._sendDisposition = function(options) {
  var dispositionOptions = _.defaults(options, {
    role: constants.linkRole.receiver,
    channel: this.session.channel,
    handle: this.handle
  });

  this.session.connection.sendFrame(
    new DispositionFrame(dispositionOptions)
  );
};

module.exports = Link;
<|endoftext|>


<commit_before>import { LD, Wall, SpritePlayer, SpriteEnemy, SpriteBullet } from "SpriteConstants";
import {
  CameraVelocity,
  FlashColor,
  FlashDuration,
  ShakeIntensity,
  ShakeDuration,
  SpriteWidth,
  SpriteHeight,
  EnemyWidth,
  EnemyHeight,
  Border,
  } from "Constants";

import Player from "objects/Character";
import Room from "objects/Room";
import Enemy from "objects/Enemy";

const needCamera = true;

const MinDivision = 1;
const MaxDivision = 5;

const Division = Math.trunc(Math.random() * (MaxDivision - MinDivision) + MinDivision);

const MaxBorder = 60;
const MinBorder = 30;

const SizeMaze = Math.trunc(Math.random() * (MaxBorder - MinBorder) + MinBorder);
// assuming SpriteWidth = SpriteHeight
const Bounds = 2 * Border + SizeMaze * SpriteWidth;

class MainMenu extends Phaser.State {

  create() {
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.game.add.sprite(50,100, LD);
    this.room = new Room(this.game);
    this.game.add.existing(this.room);

    this.hero = new Player(this.game,1000,100);
    this.game.add.existing(this.hero);

    this.enemy = new Enemy(this.game,300,100);
    this.game.add.existing(this.enemy);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }

    this.camera.follow(this.hero);
    this.room.createRandomSquare(Border,Border,SizeMaze, Division, false);
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.enemy, /*this.damage*/null, null, this);
    this.game.physics.arcade.overlap(this.hero.bullets(), this.enemy, this.kill);
    this.game.physics.arcade.overlap(this.enemy, this.room, this.pushBlock, null, this);

    this.game.physics.arcade.collide(this.hero.bullets(), this.room, this.killBullet);
    this.game.physics.arcade.collide(this.hero, this.room);
    this.enemy.follow(this.hero.body.position);
  }

  kill(enemy, bullet) {
    bullet.kill();
    enemy.kill();
  }

  killBullet(bullet) {
    bullet.kill();
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  pushBlock(enemy, block) {
    this.game.camera.shake(ShakeIntensity, ShakeDuration);
    const enemyLeft = enemy.body.position.x;
    const enemyRight = enemy.body.position.x + EnemyWidth;
    const enemyTop = enemy.body.position.y - EnemyHeight;
    const enemyBottom = enemy.body.position.y;

    const blockLeft = block.body.position.x;
    const blockRight = block.body.position.x + SpriteWidth;
    const blockTop = block.body.position.y - SpriteHeight;
    const blockBottom = block.body.position.y;

    const bigValue = 1000;
    let left = bigValue
    let right = bigValue;
    let up = bigValue;
    let down = bigValue;

    if( enemyLeft < blockLeft &&
        blockLeft < enemyRight &&
        enemyRight < blockRight
      ) {
      left = enemyRight - blockLeft;
    }

    if( blockLeft < enemyLeft &&
        enemyLeft < blockRight &&
        blockRight < enemyRight
     ) {
      right = blockRight - enemyLeft;
    }

    if( enemyTop < blockTop &&
        blockTop < enemyBottom &&
        enemyBottom < blockBottom
      ) {
      up = enemyBottom - blockTop;
    }

    if( blockTop < enemyTop &&
        enemyTop < blockBottom &&
        blockBottom < enemyBottom
    ) {
      down = blockBottom - enemyTop;
    }

    if(left < right && left < up  &&  left < down ) {
       block.body.position.x += 1;
    } else if( right < left && right < up  &&  right < down ) {
      block.body.position.x -= 1;
    } else if( up < down && up < left && up < right) {
      block.body.position.y += 1;
    } else if (down < up && down < left && down < right) {
      block.body.position.y -= 1;
    }

  }

  preload() {
    this.game.load.image(LD, "res/LD.png");
    this.game.load.image(Wall, "res/1.png");
    this.game.load.image(SpritePlayer, "res/player.png");
    this.game.load.image(SpriteEnemy, "res/enemy.png");
    this.game.load.image(SpriteBullet, "res/bullet.png");
  }

  render() {
    this.game.debug.text(Bounds, 2, 14, "#00ff00");
    //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

}

export default MainMenu;
<commit_msg>activate colission<commit_after>import { LD, Wall, SpritePlayer, SpriteEnemy, SpriteBullet } from "SpriteConstants";
import {
  CameraVelocity,
  FlashColor,
  FlashDuration,
  ShakeIntensity,
  ShakeDuration,
  SpriteWidth,
  SpriteHeight,
  EnemyWidth,
  EnemyHeight,
  Border,
  } from "Constants";

import Player from "objects/Character";
import Room from "objects/Room";
import EnemyGroup from "objects/EnemyGroup";

const needCamera = true;

const MinDivision = 1;
const MaxDivision = 5;

const Division = Math.trunc(Math.random() * (MaxDivision - MinDivision) + MinDivision);

const MaxBorder = 60;
const MinBorder = 30;

const SizeMaze = Math.trunc(Math.random() * (MaxBorder - MinBorder) + MinBorder);
// assuming SpriteWidth = SpriteHeight
const Bounds = 2 * Border + SizeMaze * SpriteWidth;

class MainMenu extends Phaser.State {

  create() {
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.game.add.sprite(50,100, LD);
    this.room = new Room(this.game);
    this.game.add.existing(this.room);

    this.hero = new Player(this.game,500,800);
    this.game.add.existing(this.hero);

    this.enemies = new EnemyGroup(this.game);
    this.game.add.existing(this.enemies);
    //this.enemy = new Enemy(this.game,300,100);
    //this.game.add.existing(this.enemy);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }

    this.camera.follow(this.hero);
    this.room.createRandomSquare(Border,Border,SizeMaze, Division);
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.enemies, /*this.damage*/null, null, this);
    this.game.physics.arcade.overlap(this.hero.bullets(), this.enemies, this.kill);
    this.game.physics.arcade.overlap(this.enemies, this.room, this.pushBlock, null, this);

    this.game.physics.arcade.collide(this.hero.bullets(), this.room, this.killBullet);
    this.game.physics.arcade.collide(this.hero, this.room);
    this.enemies.follow(this.hero.body.position);
    //this.moveCamera()
  }

  kill(enemy, bullet) {
    bullet.kill();
    enemy.kill();
  }

  killBullet(bullet) {
    bullet.kill();
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  pushBlock(enemy, block) {
    this.game.camera.shake(ShakeIntensity, ShakeDuration);
    const enemyLeft = enemy.body.position.x;
    const enemyRight = enemy.body.position.x + EnemyWidth;
    const enemyTop = enemy.body.position.y - EnemyHeight;
    const enemyBottom = enemy.body.position.y;

    const blockLeft = block.body.position.x;
    const blockRight = block.body.position.x + SpriteWidth;
    const blockTop = block.body.position.y - SpriteHeight;
    const blockBottom = block.body.position.y;

    const bigValue = 1000;
    let left = bigValue
    let right = bigValue;
    let up = bigValue;
    let down = bigValue;

    if( enemyLeft < blockLeft &&
        blockLeft < enemyRight &&
        enemyRight < blockRight
      ) {
      left = enemyRight - blockLeft;
    }

    if( blockLeft < enemyLeft &&
        enemyLeft < blockRight &&
        blockRight < enemyRight
     ) {
      right = blockRight - enemyLeft;
    }

    if( enemyTop < blockTop &&
        blockTop < enemyBottom &&
        enemyBottom < blockBottom
      ) {
      up = enemyBottom - blockTop;
    }

    if( blockTop < enemyTop &&
        enemyTop < blockBottom &&
        blockBottom < enemyBottom
    ) {
      down = blockBottom - enemyTop;
    }

    if(left < right && left < up  &&  left < down ) {
       block.body.position.x += 1;
    } else if( right < left && right < up  &&  right < down ) {
      block.body.position.x -= 1;
    } else if( up < down && up < left && up < right) {
      block.body.position.y += 1;
    } else if (down < up && down < left && down < right) {
      block.body.position.y -= 1;
    }

  }

  preload() {
    this.game.load.image(LD, "res/LD.png");
    this.game.load.image(Wall, "res/1.png");
    this.game.load.image(SpritePlayer, "res/player.png");
    this.game.load.image(SpriteEnemy, "res/enemy.png");
    this.game.load.image(SpriteBullet, "res/bullet.png");
  }

  render() {
    this.game.debug.text(Bounds, 2, 14, "#00ff00");
    //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

}

export default MainMenu;
<|endoftext|>


<commit_before>
/*!  jquery-holdup - */

/*  *** USAGE ***
    JavaScript:
        // these are the open or commonly used api methods
        $(selector).holdup({override_options})     // create instance
        $(selector).holdup('render')               // will determine if element should be shown
        $(selector).holdup('show')                 // will force elements to be loaded

        // these are exposed really for debugging purposes...
        $(selector).holdup('observe')              // will add container ( window ) event listeners if listeners have not been added
        $(selector).holdup('ignore')               // will remove container ( window ) event listeners

    HTML:
        // NOTE: based on DEFAULT options
        // src-retina path is for displays that support hi-dpi images

    CSS:
        // NOTE: based on DEFAULT options
        .heldup {
            rules ... rules
        }
        .heldup.heldup-success {
            rules ... rules
        }
        .heldup.heldup-error{
            rules ... rules
        }
*/
;(function($)
{
    'use strict';

    /* HELPER FUNCTIONS */
    // PURPOSE: check if element is in view to display
    // @param $container : $(DOMElement) of the scrollable view
    // @param $el : $(DOMElement)
    // @param threshold : Number
    // return bool
    var is_element_in_view = function( $container, $el, threshold )
    {
        // PURPOSE: check if element is in vertical viewport
        // @param el_top : Number
        // return bool
        var is_element_in_vertical_view = function( top )
        {
            var container_viewport_top = $container.scrollTop();
            return top + $el.height() >= container_viewport_top - threshold &&     // element bottom is within the viewport top
                top <= container_viewport_top + $container.height() + threshold    // element top is within the viewport bottom
            ;
        };

        // PURPOSE: check if element is in horizontal viewport
        // @param el_left : Number
        // return bool
        var is_element_in_horizontal_view = function( left )
        {
            var container_viewport_left = $container.scrollLeft();
            return left <= container_viewport_left + $container.width() &&         // element left is within the viewport right
                left + $el.width() >= container_viewport_left                      // element right is within the viewport left
            ;
        };

        // cache the element's coordinates on the page...
        var element_offset = $el.offset();

        return  is_element_in_vertical_view( element_offset.top ) &&
                is_element_in_horizontal_view( element_offset.left );
    };

    // PURPOSE: see if there are any more images to load -- see if rendering needs to be run
    // @param evt : $(Event)
    var do_render_view = function(evt)
    {
        // don't fire unless its by a human
        if (evt.isTrigger)
        {
            return;
        }
        // selects the imgs not loaded
        var $imgs_not_loaded = $('.' + pending_classname);
        // do the render method
        if ($imgs_not_loaded.length)
        {
            $imgs_not_loaded.holdup('render');
        }
        // or destroy the window events
        else if (is_initialized)
        {
            HoldupProto.ignore();
        }
        // or nothing at all
    };

    var get_now = Date.now || function()
    {
        return (new Date()).getTime();
    };

    var do_bottlenecked_event = function(fn, delay, is_resize)
    {
        var that;                       // pointer for scoped context
        var args;                       // pointer for scoped arguments
        var result;                     // pointer for returned value of function
        var timeout = null;             // window Timeout reference
        var last_timestap = 0;          // date int
        var do_call = function()
        {
            result = fn.apply(that, args);
            timeout = that = args = null;
        };
        var call_me_maybe = function()
        {
            last_timestap = is_resize ? 0 : get_now();
            do_call();
        };
        return function(/*arguments*/)
        {
            var now = get_now();
            if (!last_timestap && is_resize)
            {
                last_timestap = now;
            }
            var remaining = delay - (now - last_timestap);
            that = this;
            args = arguments;
            if (remaining <= 0)
            {
                clearTimeout(timeout);
                last_timestap = now;
                do_call();
            }
            else if (!timeout && !is_resize)
            {
                timeout = setTimeout(call_me_maybe, remaining);
            }
            return result;
        };
    };

    // wrap deferments of invocation around render function
    var do_scroll_browser_event = do_bottlenecked_event(do_render_view, 300);
    var do_resize_browser_event = do_bottlenecked_event(do_render_view, 250, true);

    // PURPOSE: load image and handle error and fail events
    // @param $el : $(DOMElement)
    // @param options : { options }
    // return undefined
    var do_load_image = function($el, options)
    {
        var do_handle_error = function()
        {
            // add error className
            $el
                .removeClass(pending_classname + ' ' + options.successClass)
                .addClass(options.errorClass)
                ;

            // run error callback... no arguments or context...
            if (options.onError)
            {
                options.onError();
            }
        };

        var do_handle_sucess = function()
        {
            // NOTE: this logic allows usage on elements -- not just
            if ($el.is('img'))
            {
                // set img.src property if element is an
                // set src prop and add success className
                $el.prop('src', data_source_val)
                    .removeClass(pending_classname + ' ' + options.errorClass)
                    .addClass(options.successClass)
                    ;
            }
            // set background-image style tag if element is something else like a
 or
            else
            {
                $el.css('background-image', 'url("' + data_source_val + '")');
            }

            // run success callback... no arguments or context...
            if (options.onSuccess)
            {
                options.onSuccess();
            }
        };

        // get the path to the img in an html data-* attr
        var data_source_val = $el.data(options.srcAttr) || $el.data(default_attr_name);
        var img;

        if (data_source_val)
        {
            // create element
            img = new Image();
            // set events
            img.onerror = do_handle_error;
            img.onload = do_handle_sucess;
            // load image
            img.src = data_source_val;
        }
        else
        {
            do_handle_error();
        }
    };

    // constants
    var $el_scrollable = $(window);
    // the private resize event namespace
    var resize_event_name = 'resize.holdup';
    // the private scroll event namespace
    var scroll_event_name = 'scroll.holdup';
    // the additional className to define image load has successfully completed -- static to keep render routine consistent
    var pending_classname = 'holdup-notloaded';
    // 'original' is the default to support lazyload's default markup expectations
    var default_attr_name = 'src';
    // boolean to determine if plugin has been initialized for plugin window event logic
    var is_initialized = false;

    // reference for holdup jQuery PLUGIN
    var old = $.fn.holdup;

    /* Yoholdup CONSTRUCTOR */
    // @param element : DOMElement
    // @param options : { options }
    var Holdup = function(element, options)
    {
        var that = this;
        // define this instance's set of options
        var these_options = that.options = $.extend({}, Holdup.DEFAULTS, options);

        // save reference to element
        that.$el = $(element)
            // add base className & add waiting state className
            .addClass(these_options.baseClass+' '+pending_classname)
            // and placeholder img
            .prop('src', these_options.placeholder)
            ;

        // set property
        that.isloaded = false;

        // do instance show
        that.observe();
        that.render();
    };

    // public methods
    var HoldupProto = Holdup.prototype;

    // PURPOSE: force show a specific element
    HoldupProto.show = function()
    {
        do_load_image(this.$el, this.options);
    };

    HoldupProto.render = function()
    {
        // proceed if element is visible and not loaded
        if (!this.isloaded && is_element_in_view($el_scrollable, this.$el, this.options.threshold) )
        {
            this.show();
        }
    };

    // PURPOSE: add plugin window events
    HoldupProto.observe = function()
    {
        // avoids binding events too much
        if (!is_initialized)
        {
            // bind events
            $el_scrollable
                .on(scroll_event_name, do_scroll_browser_event)
                .on(resize_event_name, do_resize_browser_event)
                ;
            // set flag
            is_initialized = true;
        }
    };

    // PURPOSE: remove plugin window events
    HoldupProto.ignore = function()
    {
        // unbind
        $el_scrollable
            .off(scroll_event_name)
            .off(resize_event_name)
            ;
        // set flag
        is_initialized = false;
    };

    // define initial default options
    Holdup.DEFAULTS = {
        // the initialized className to define image load has been bound to element
        'baseClass': 'heldup',
        // the additional className to define image load has unsuccessfully completed
        'errorClass': 'heldup-error',
        // the additional className to define image load has successfully completed
        'successClass': 'heldup-success',
        // define callbacks to null
        // will execute when user adds option
        'onSuccess': null,
        'onError': null,
        // default placeholder for when the images are not loaded which is a 1x1 transparent gif
        'placeholder': 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
        // define slack of logic determining what' in the viewport
        'threshold': 0,
        // define the data attr to source the actual image -- if retina is found it toggles the default attr name
        'srcAttr': window.devicePixelRatio > 1 ? 'src-retina' : default_attr_name
    };

    // assign to {$.fn} namespace
    $.fn.holdup = function(option)
    {
        return this.each(function()
        {
            var $this = $(this);
            var data = $this.data('holdup');

            // create new instance
            if (!data)
            {
                $this.data('holdup', (data = new Holdup(this, typeof option === 'object' && option)));
            }
            // execute instance method
            else if (typeof option === 'string' && data[option] )
            {
                data[option]();
            }
        });
    };

    // set access to the plugin constructor to expose defaults and potentially allow DEFAULTS override...
    $.fn.holdup.Constructor = Holdup;

    /*
        // Holdup NO CONFLICT to reassign namespace
        **** USAGE
        var original_holdup = $.fn.Holdup.noConflict()      // return $.fn.holdup to previously assigned value
        $.fn.someOtherNamespace = original_holdup           // give $().someOtherNamespace the yoholdup functionality
    */
    $.fn.holdup.noConflict = function()
    {
        $.fn.Holdup = old;
        return this;
    };

})(jQuery);
<commit_msg>make plugin and compatible<commit_after>
/*!  jquery-holdup - */

/* global define:false */

/*  *** USAGE ***
    JavaScript:
        // these are the open or commonly used api methods
        $(selector).holdup({override_options})     // create instance
        $(selector).holdup('render')               // will determine if element should be shown
        $(selector).holdup('show')                 // will force elements to be loaded

        // these are exposed really for debugging purposes...
        $(selector).holdup('observe')              // will add container ( window ) event listeners if listeners have not been added
        $(selector).holdup('ignore')               // will remove container ( window ) event listeners

    HTML:
        // NOTE: based on DEFAULT options
        // src-retina path is for displays that support hi-dpi images

    CSS:
        // NOTE: based on DEFAULT options
        .heldup {
            rules ... rules
        }
        .heldup.heldup-success {
            rules ... rules
        }
        .heldup.heldup-error{
            rules ... rules
        }
*/
;( function ( factory )
{
    'use strict';

    if ( typeof define === 'function' && define.amd )
    {
        // AMD. Register as an anonymous module.
        define( ['jquery'], factory );
    }
    else
    {
        // Browser globals
        factory( jQuery );
    }
}
( function ( $ )
{
    'use strict';

    /* HELPER FUNCTIONS */
    // PURPOSE: check if element is in view to display
    // @param $container : $(DOMElement) of the scrollable view
    // @param $el : $(DOMElement)
    // @param threshold : Number
    // return bool
    var is_element_in_view = function( $container, $el, threshold )
    {
        // PURPOSE: check if element is in vertical viewport
        // @param el_top : Number
        // return bool
        var is_element_in_vertical_view = function( top )
        {
            var container_viewport_top = $container.scrollTop();
            return top + $el.height() >= container_viewport_top - threshold &&     // element bottom is within the viewport top
                top <= container_viewport_top + $container.height() + threshold    // element top is within the viewport bottom
                ;
        };

        // PURPOSE: check if element is in horizontal viewport
        // @param el_left : Number
        // return bool
        var is_element_in_horizontal_view = function( left )
        {
            var container_viewport_left = $container.scrollLeft();
            return left <= container_viewport_left + $container.width() &&         // element left is within the viewport right
                left + $el.width() >= container_viewport_left                      // element right is within the viewport left
                ;
        };

        // cache the element's coordinates on the page...
        var element_offset = $el.offset();

        return  is_element_in_vertical_view( element_offset.top ) &&
                is_element_in_horizontal_view( element_offset.left )
                ;
    };

    // PURPOSE: see if there are any more images to load -- see if rendering needs to be run
    // @param evt : $(Event)
    var do_render_view = function( evt )
    {
        // don't fire unless its by a human
        if (evt.isTrigger)
        {
            return;
        }
        // selects the imgs not loaded
        var $imgs_not_loaded = $('.' + pending_classname);
        // do the render method
        if ($imgs_not_loaded.length)
        {
            $imgs_not_loaded.holdup('render');
        }
        // or destroy the window events
        else if (is_initialized)
        {
            HoldupProto.ignore();
        }
        // or nothing at all
    };

    var do_get_now = Date.now || function()
    {
        return (new Date()).getTime();
    };

    var do_bottlenecked_event = function( fn, delay, is_resize )
    {
        var that;                       // pointer for scoped context
        var args;                       // pointer for scoped arguments
        var result;                     // pointer for returned value of function
        var timeout = null;             // window Timeout reference
        var last_timestap = 0;          // date int
        var do_call = function()
        {
            result = fn.apply(that, args);
            timeout = that = args = null;
        };
        var call_me_maybe = function()
        {
            last_timestap = is_resize ? 0 : do_get_now();
            do_call();
        };
        return function(/*arguments*/)
        {
            var now = do_get_now();
            if (!last_timestap && is_resize)
            {
                last_timestap = now;
            }
            var remaining = delay - (now - last_timestap);
            that = this;
            args = arguments;
            if (remaining <= 0)
            {
                clearTimeout(timeout);
                last_timestap = now;
                do_call();
            }
            else if (!timeout && !is_resize)
            {
                timeout = setTimeout(call_me_maybe, remaining);
            }
            return result;
        };
    };

    // wrap deferments of invocation around render function
    var do_scroll_browser_event = do_bottlenecked_event(do_render_view, 300);
    var do_resize_browser_event = do_bottlenecked_event(do_render_view, 250, true);

    // PURPOSE: load image and handle error and fail events
    // @param $el : $(DOMElement)
    // @param options : { options }
    // return undefined
    var do_load_image = function( $el, options )
    {
        var do_handle_error = function()
        {
            // add error className
            $el
                .removeClass(pending_classname + ' ' + options.successClass)
                .addClass(options.errorClass)
                ;

            // run error callback... no arguments or context...
            if (options.onError)
            {
                options.onError();
            }
        };

        var do_handle_sucess = function()
        {
            // NOTE: this logic allows usage on elements -- not just
            if ($el.is('img'))
            {
                // set img.src property if element is an
                // set src prop and add success className
                $el.prop('src', data_source_val)
                    .removeClass(pending_classname + ' ' + options.errorClass)
                    .addClass(options.successClass)
                    ;
            }
            // set background-image style tag if element is something else like a
 or
            else
            {
                $el.css('background-image', 'url("' + data_source_val + '")');
            }

            // run success callback... no arguments or context...
            if (options.onSuccess)
            {
                options.onSuccess();
            }
        };

        // get the path to the img in an html data-* attr
        var data_source_val = $el.data( options.srcAttr ) || $el.data( default_attr_name );
        var img;

        if (data_source_val)
        {
            // create element
            img = new Image();
            // set events
            img.onerror = do_handle_error;
            img.onload = do_handle_sucess;
            // load image
            img.src = data_source_val;
        }
        else
        {
            do_handle_error();
        }
    };

    // constants
    var $el_scrollable = $(window);
    // the private resize event namespace
    var resize_event_name = 'resize.holdup';
    // the private scroll event namespace
    var scroll_event_name = 'scroll.holdup';
    // the additional className to define image load has successfully completed -- static to keep render routine consistent
    var pending_classname = 'holdup-notloaded';
    // 'original' is the default to support lazyload's default markup expectations
    var default_attr_name = 'src';
    // boolean to determine if plugin has been initialized for plugin window event logic
    var is_initialized = false;

    // reference for holdup jQuery PLUGIN
    var old = $.fn.holdup;

    /* Yoholdup CONSTRUCTOR */
    // @param element : DOMElement
    // @param options : { options }
    var Holdup = function( element, options )
    {
        var that = this;
        // define this instance's set of options
        var these_options = that.options = $.extend({}, Holdup.DEFAULTS, options);

        // save reference to element
        that.$el = $(element)
            // add base className & add waiting state className
            .addClass(these_options.baseClass+' '+pending_classname)
            // and placeholder img
            .prop('src', these_options.placeholder)
            ;

        // set property
        that.isloaded = false;

        // do instance show
        that.observe();
        that.render();
    };

    // public methods
    var HoldupProto = Holdup.prototype;

    // PURPOSE: force show a specific element
    HoldupProto.show = function()
    {
        do_load_image(this.$el, this.options);
    };

    HoldupProto.render = function()
    {
        // proceed if element is visible and not loaded
        if (!this.isloaded && is_element_in_view($el_scrollable, this.$el, this.options.threshold) )
        {
            this.show();
        }
    };

    // PURPOSE: add plugin window events
    HoldupProto.observe = function()
    {
        // avoids binding events too much
        if (!is_initialized)
        {
            // bind events
            $el_scrollable
                .on(scroll_event_name, do_scroll_browser_event)
                .on(resize_event_name, do_resize_browser_event)
                ;
            // set flag
            is_initialized = true;
        }
    };

    // PURPOSE: remove plugin window events
    HoldupProto.ignore = function()
    {
        // unbind
        $el_scrollable
            .off(scroll_event_name)
            .off(resize_event_name)
            ;
        // set flag
        is_initialized = false;
    };

    // define initial default options
    Holdup.DEFAULTS = {
        // the initialized className to define image load has been bound to element
        'baseClass': 'heldup',
        // the additional className to define image load has unsuccessfully completed
        'errorClass': 'heldup-error',
        // the additional className to define image load has successfully completed
        'successClass': 'heldup-success',
        // define callbacks to null
        // will execute when user adds option
        'onSuccess': null,
        'onError': null,
        // default placeholder for when the images are not loaded which is a 1x1 transparent gif
        'placeholder': 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
        // define slack of logic determining what' in the viewport
        'threshold': 0,
        // define the data attr to source the actual image -- if retina is found it toggles the default attr name
        'srcAttr': window.devicePixelRatio > 1 ? 'src-retina' : default_attr_name
    };

    // assign to {$.fn} namespace
    $.fn.holdup = function( option )
    {
        return this.each(function()
        {
            var $this = $(this);
            var data = $this.data('holdup');

            // create new instance
            if (!data)
            {
                $this.data('holdup', (data = new Holdup(this, typeof option === 'object' && option)));
            }
            // execute instance method
            else if (typeof option === 'string' && data[option] )
            {
                data[option]();
            }
        });
    };

    // set access to the plugin constructor to expose defaults and potentially allow DEFAULTS override...
    $.fn.holdup.Constructor = Holdup;

    /*
        // Holdup NO CONFLICT to reassign namespace
        **** USAGE
        var original_holdup = $.fn.Holdup.noConflict()      // return $.fn.holdup to previously assigned value
        $.fn.someOtherNamespace = original_holdup           // give $().someOtherNamespace the yoholdup functionality
    */
    $.fn.holdup.noConflict = function()
    {
        $.fn.Holdup = old;
        return this;
    };

    return $.fn.holdup;

}));
<|endoftext|>


<commit_before>var Stream = require('./stream');
var Load = require('./load');
var Parse = require('./parse');

module.exports = function Link (scope, event, options) {

    var stream = Stream.Pass();

    // buffer writes until event stream is setup
    stream.cork();
    stream.on('_flow_err', stream.emit.bind(stream, 'error'));

    // load instance, parse event and get flow stream sequences
    Load(scope, stream, event[0], options).once('_flow_load', function (instance) {

        console.log('flow load:', instance);

        Parse(scope, stream, instance, event[1], options).once('_flow_event', function (sequence) {

            console.log('flow event:', sequence);

            // ..seq
            //sequence.s.forEach(this.emit.bind(this, '_flow_seq', instance));
            //this.emit('_flow_end', instance);
            sequence.s.forEach(function (sequence) {
                console.log('LINK SEQUENCE:', sequence);
                // TODO

                var seqStream = new Stream.Event();

                // append sequence
                if (sequence.s) {
                    seqStream.seq = sequence;
                }

                // callstream handler: sequence.p
                var stream_handler = typeof sequence.p[1] === 'string' ? sequence.p[0].flow(sequence.p[1]) : sequence.p[1].call(sequence.p[0]);

                // ..link streams
                stream = stream.pipe(seqStream).pipe(stream_handler);
            });

            console.log('LINK SEQ END');

            //stream.pipe(stream);
            stream.emit('ready');
            stream.uncork();
        });
    });

    return stream;
}

function linkSequence (stream) {

}

    /*
    var input = initial.i;
    var first = true;
    var errEvent;
    var handleError = function (err) {

        // emit error on origin ouput stream
        initial.o.emit('error', err);

        // write error to error event
        if (event_stream.r) {
            errEvent = errEvent || instance.flow(event_stream.r, options);
            if (errEvent.ready) {
                errEvent.i.write(err);
            } else {
                errEvent.i.on('ready', function () {
                    errEvent.i.write(err);
                });
            }

            // end error stream on initial end
            initial.o.on('end', errEvent.i.end.bind(errEvent));
        }

        // TODO keep streams piped
        // https://github.com/nodejs/node/issues/3045#issuecomment-142975237
    };

    // end handler
    if (event_stream.e) {
        initial.o.on('end', function () {
            if (!initial.i._errEH) {
                instance.flow(event_stream.e, options).i.on('ready', function () {
                    endEvent.i.end(options);
                });
            }
        });
    }

    // emit error event on initial error
    initial.i.on('error', handleError);

    event_stream.d.forEach(function (section, index) {

        // create a new sub-stream to call handlers
        var output = Stream.Event(options);
        output.seq = section[0];
        output.on('error', handleError);

        // tee streams
        if (section[1] && section[1][0] === '|' || first) {
            input.pipe(output);
            first = false;
        }

        // pipe to next stream
        if (section[1]) {

            if (typeof section[1][1] === 'string') {
                var fes = instance.flow(section[1][1], options);
                input.pipe(fes.i);
                fes.o.on('error', output.emit.bind(output, 'error'));
                fes.o.pipe(output);

            } else if (typeof section[1][1][0] === 'function') {

                // attach flow composition options to caller arguments
                options._ = section[1][1][1] || {};

                // call stream handler
                section[1][1][0].call(
                    section[1][1][2],
                    {i: input, o: output},
                    options,
                    handleError
                );
            }
        }

        // event stream sequence handler is the new input
        input = output;
    });

    input.pipe(initial.o);

    // read out data if no data listener is added, to prevent buffer overflow
    if (!initial.o._events.data) {
        initial.o.on('data', function (chunk) {
            console.error(new Error('Flow: Uncaught data chunk: Event:',instance._name + '/' + event));
        });
    }
    */
<commit_msg>work in progress for more efficient stream linking<commit_after>var Stream = require('./stream');
var Load = require('./load');
var Parse = require('./parse');

module.exports = function Link (scope, event, options) {

    var stream = Stream.Event();

    // buffer writes until event stream is setup
    stream.cork();

    // load instance, parse event and get flow stream sequences
    Load(scope, stream, event[0], options).once('_flow_load', function (instance) {
        Parse(scope, stream, instance, event[1], options).once('_flow_event', function (event) {

            var node;
            event.s.forEach(function (sequence) {

                // writable / transform
                node = node ? node.pipe(new Stream.Event(options)) : stream;
                // TODO node.on('error', stream.emit.bind(stream, 'error'));

                // append sequence
                if (sequence.s) {
                    node.seq = sequence.s;
                }

                // TODO tee streams  sequence.n = '|'

                if (sequence.p) {

                    // pipe to flow event
                    if (typeof sequence.p[1] === 'string') {
                        node = node.pipe(sequence.p[0].flow(sequence.p[1], options));
                        node.on('error', stream.emit.bind(stream, 'error'));

                    // call stream handler
                    } else {
                        options._ = sequence.a || {};
                        node = node.pipe(sequence.p[1].call(sequence.p[0], options));
                        node.on('error', stream.emit.bind(stream, 'error'));
                    }
                }
            });

            // write back to stream (test inifite loop)
            node.pipe(stream);
            stream.emit('ready');
            stream.uncork();
        });
    });

    return stream;
}

/*
var input = initial.i;
var first = true;
var errEvent;
var handleError = function (err) {

    // emit error on origin ouput stream
    initial.o.emit('error', err);

    // write error to error event
    if (event_stream.r) {
        errEvent = errEvent || instance.flow(event_stream.r, options);
        if (errEvent.ready) {
            errEvent.i.write(err);
        } else {
            errEvent.i.on('ready', function () {
                errEvent.i.write(err);
            });
        }

        // end error stream on initial end
        initial.o.on('end', errEvent.i.end.bind(errEvent));
    }

    // TODO keep streams piped
    // https://github.com/nodejs/node/issues/3045#issuecomment-142975237
};

// end handler
if (event_stream.e) {
    initial.o.on('end', function () {
        if (!initial.i._errEH) {
            instance.flow(event_stream.e, options).i.on('ready', function () {
                endEvent.i.end(options);
            });
        }
    });
}

// read out data if no data listener is added, to prevent buffer overflow
if (!initial.o._events.data) {
    initial.o.on('data', function (chunk) {
        console.error(new Error('Flow: Uncaught data chunk: Event:',instance._name + '/' + event));
    });
}
*/
<|endoftext|>


<commit_before>(function() {
  'use strict';

  /**
   * Storage Class implementation. Stores and retrieves data from remote
   * storage.
   * @constructor
   * @extends {EventEmitter}
   * @param {string} storageRef Reference to the remote storage entity.
   * @param {Object=} opt_config optional Configuration object
   */
  lfr.Storage = function(storageRef, opt_config) {
    this._storageRef = storageRef;

    // Create a queue in order to keep the messages in safe
    this._queue = [];

    // Attach listener to dataAdded event to track adding messages to the queue and start sending them.
    this.on('dataAdded', this._processQueue, this);

    this.on('dataReceived', this._onDataReceived, this);
  };
  lfr.inherits(lfr.Storage, lfr.EventEmitter);

  lfr.Storage.STATUS_ERROR = -1;

  lfr.Storage.STATUS_PENDING = 1;

  lfr.Storage.STATUS_SENT = 0;

  lfr.Storage.ERROR_NETWORK_FAILURE = 1;

  /**
   * Queries data from storage.
   * @param {Object} value Object containing data to be requested.
   * @param {Function=} opt_callback optional Callback function which will
   *   be invoked once the data is stored.
   * @param {Object=} opt_config optional Data payload to be provided to the
   *   storage.
   */
  lfr.Storage.prototype.query = function(value, opt_callback, opt_config) {
    // TODO
  };

  /**
   * Stores the provided data to the database.
   * @param {Object|string|number} value The value which should be stored to
   * the storage.
   * @param {Function=} opt_callback optional Callback function which will be
   *   invoked once the data is stored.
   * @param {Object=} opt_config optional Data payload to be provided to the
   *   storage.
   */
  lfr.Storage.prototype.set = function(value, opt_callback, opt_config) {
    var valType = typeof val;

    if (valType !== 'object' || valType !== 'number' || valType !== 'string') {
      return false;
    }

    // Generate an messageId, it will be sent to server, so messages won't be duplicated there
    // and we will be able to recognize the messages exchanged with the server
    var messageId = this._generateId();

    // Construct the message object, we will store this to the queue
    var message = {
      messageId: messageId,
      data: value
    };

    // Store the object to the queue as the last element
    this._queue.push({
      callback: opt_callback,
      messageId: messageId,
      message: message,
      status: {
        code: lfr.Transport.STATUS_PENDING
      }
    });

    // Emit an event that data has been added to the queue.
    this.emit('dataAdded', message);
  };

  /**
   * Generates Id using the current time and randomly generated number.
   * @protected
   * @return {string} The generated Id
   */
  lfr.Storage.prototype._generateId = function() {
    var now = Date.now ? Date.now() : new Date().getTime();

    var randomNum = this._getRandomNumber();

    return '-' + now + '-' + String(randomNum).replace('.', '') + '-';
  };

  /**
   * Generates random number between some range of numbers.
   * @protected
   * @param {number=} opt_min optional The min value. Default: 1
   * @param {number=} opt_max optional The max number. Default: 100000
   * @return {Number} The generated number.
   */
  lfr.Storage.prototype.getRandomNumber_ = function(opt_min, opt_max) {
    var min = min || 1;
    var max = max || 100000;

    return Math.random() * (max - min) + min;
  };

  /**
   * Event listener to dataReceived event.
   * @protected
   * @param {object} event EventFacade object
   */
  lfr.Storage.prototype.onDataReceived_ = function(event) {
    var value = event.val;

    for (var i = 0; i < this._queue.length; ++i) {
      var queueMessage = this._queue[i];

      // Check if current message in the queue has the same messageId as those which came from the server.
      if (queueMessage.messageId === value.messageId) {

        // If the status is sent, remove it from the queue and emit an event
        if (value.status === lfr.Storage.STATUS_SENT) {
          this._queue.splice(i, 1);

          this.emit('messageReceived', queueMessage.message);
        } else {
          // change the status to error with the response code as provided from the server
          queueMessage.status = {
            code: lfr.Transport.STATUS_ERROR,
            reason: value.code
          };
        }
      }
    }
  };

  /**
   * Processes the queue and sends all unsent or previously failed messages.
   * @protected
   */
  lfr.Storage.prototype.processQueue_ = function() {
    // We clear here the timeout because there are two ways to invoke this function:
    // 1. As result of firing dataAdded event
    // 2. As result of timeout
    //
    // There could be situation like this:
    // - dataAdded has been emitd, so this function will be invoked
    // - however, previously this function has started already a timeout and it will be
    // invoked in some time.
    //
    // In this case we have to cancel the timeout, process the queue and start it again,
    // if there are still messages.

    clearTimeout(this._processQueue);

    for (var i = 0; i < this._queue.length; ++i) {
      var queueMessage = this._queue[i];

      // We will send messages which are pending or failed, but with network failure error only
      if (status.code === lfr.Transport.STATUS_PENDING ||
        (status.code === lfr.Transport.STATUS_ERROR && status.reason === lfr.Transport.ERROR_NETWORK_FAILURE)) {

        var userMessage = queueMessage.message;

        lfr.Transport.getSingleton().send(userMessage);

        queueMessage.status = lfr.Transport.STATUS_SENT;
      }
    }

    if (this._queue.length) {
      this._processQueue = setTimeout(this._processQueue, 500);
    }
  };
}());<commit_msg>Source formatting<commit_after>(function() {
  'use strict';

  /**
   * Storage Class implementation. Stores and retrieves data from remote
   * storage.
   * @constructor
   * @extends {EventEmitter}
   * @param {string} storageRef Reference to the remote storage entity.
   * @param {Object=} opt_config optional Configuration object
   */
  lfr.Storage = function(storageRef, opt_config) {
    this.storageRef_ = storageRef;

    // Create a queue in order to keep the messages in safe
    this.queue_ = [];

    // Attach listener to dataAdded event to track adding messages to the queue and start sending them.
    this.on('dataAdded', this.processQueue_, this);

    this.on('dataReceived', this.onDataReceived_, this);
  };
  lfr.inherits(lfr.Storage, lfr.EventEmitter);

  lfr.Storage.STATUS_ERROR = -1;

  lfr.Storage.STATUS_PENDING = 1;

  lfr.Storage.STATUS_SENT = 0;

  lfr.Storage.ERROR_NETWORK_FAILURE = 1;

  /**
   * Queries data from storage.
   * @param {Object} value Object containing data to be requested.
   * @param {Function=} opt_callback optional Callback function which will
   *   be invoked once the data is stored.
   * @param {Object=} opt_config optional Data payload to be provided to the
   *   storage.
   */
  lfr.Storage.prototype.query = function(value, opt_callback, opt_config) {
    // TODO
  };

  /**
   * Stores the provided data to the database.
   * @param {Object|string|number} value The value which should be stored to
   * the storage.
   * @param {Function=} opt_callback optional Callback function which will be
   *   invoked once the data is stored.
   * @param {Object=} opt_config optional Data payload to be provided to the
   *   storage.
   */
  lfr.Storage.prototype.set = function(value, opt_callback, opt_config) {
    var valType = typeof val;

    if (valType !== 'object' || valType !== 'number' || valType !== 'string') {
      return false;
    }

    // Generate an messageId, it will be sent to server, so messages won't be duplicated there
    // and we will be able to recognize the messages exchanged with the server
    var messageId = this.generateId_();

    // Construct the message object, we will store this to the queue
    var message = {
      messageId: messageId,
      data: value
    };

    // Store the object to the queue as the last element
    this.queue_.push({
      callback: opt_callback,
      messageId: messageId,
      message: message,
      status: {
        code: lfr.Transport.STATUS_PENDING
      }
    });

    // Emit an event that data has been added to the queue.
    this.emit('dataAdded', message);
  };

  /**
   * Generates Id using the current time and randomly generated number.
   * @protected
   * @return {string} The generated Id
   */
  lfr.Storage.prototype._generateId = function() {
    var now = Date.now ? Date.now() : new Date().getTime();

    var randomNum = this.getRandomNumber_();

    return '-' + now + '-' + String(randomNum).replace('.', '') + '-';
  };

  /**
   * Generates random number between some range of numbers.
   * @protected
   * @param {number=} opt_min optional The min value. Default: 1
   * @param {number=} opt_max optional The max number. Default: 100000
   * @return {Number} The generated number.
   */
  lfr.Storage.prototype.getRandomNumber_ = function(opt_min, opt_max) {
    var min = min || 1;
    var max = max || 100000;

    return Math.random() * (max - min) + min;
  };

  /**
   * Event listener to dataReceived event.
   * @protected
   * @param {object} event EventFacade object
   */
  lfr.Storage.prototype.onDataReceived_ = function(event) {
    var value = event.val;

    for (var i = 0; i < this.queue_.length; ++i) {
      var queueMessage = this.queue_[i];

      // Check if current message in the queue has the same messageId as those which came from the server.
      if (queueMessage.messageId === value.messageId) {

        // If the status is sent, remove it from the queue and emit an event
        if (value.status === lfr.Storage.STATUS_SENT) {
          this.queue_.splice(i, 1);

          this.emit('messageReceived', queueMessage.message);
        } else {
          // change the status to error with the response code as provided from the server
          queueMessage.status = {
            code: lfr.Transport.STATUS_ERROR,
            reason: value.code
          };
        }
      }
    }
  };

  /**
   * Processes the queue and sends all unsent or previously failed messages.
   * @protected
   */
  lfr.Storage.prototype.processQueue_ = function() {
    // We clear here the timeout because there are two ways to invoke this function:
    // 1. As result of firing dataAdded event
    // 2. As result of timeout
    //
    // There could be situation like this:
    // - dataAdded has been emitd, so this function will be invoked
    // - however, previously this function has started already a timeout and it will be
    // invoked in some time.
    //
    // In this case we have to cancel the timeout, process the queue and start it again,
    // if there are still messages.

    clearTimeout(this.processQueueHandler_);

    for (var i = 0; i < this.queue_.length; ++i) {
      var queueMessage = this.queue_[i];

      // We will send messages which are pending or failed, but with network failure error only
      if (status.code === lfr.Transport.STATUS_PENDING ||
        (status.code === lfr.Transport.STATUS_ERROR && status.reason === lfr.Transport.ERROR_NETWORK_FAILURE)) {

        var userMessage = queueMessage.message;

        lfr.Transport.getSingleton().send(userMessage);

        queueMessage.status = lfr.Transport.STATUS_SENT;
      }
    }

    if (this.queue_.length) {
      this.processQueueHandler_ = setTimeout(this.processQueue_, 500);
    }
  };
}());<|endoftext|>


<commit_before>/**
 * jQuery.clabel - Compact label. Converts all selected LABEL_TEXT
 * tags into <input value="LABEL_TEXT">.
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * @author Johnny Human <http://lab.aam.me/jquery-clabel/>
 **/

(function($){
    $.fn.clabel = function(options) {
        var defaults = {
            class:       "clabel-set",
            class_focus: ""
        };

        var options = $.extend(defaults, options);

        return this.each(function() {
            var label = $('label[for=' + $(this).attr('id') + ']').text();
            $('label[for=' + $(this).attr('id') + ']').remove();

            $(this).addClass(options.class);
            $(this).val(label);

            $($(this)).unbind().bind("blur focus", function() {
                if ($(this).hasClass(options.class)) {
                    $(this).val("");
                    $(this).removeClass(options.class);
                } else if ($(this).val() == "") {
                    $(this).addClass(options.class);
                    $(this).val(label);
                }
            });
        });
    };
})(jQuery);
<commit_msg>Closes #2. Minor description edits.<commit_after>/**
 * jQuery cLabel plugin
 *
 * Converts all selected LABEL_TEXT tags
 * into <input value="LABEL_TEXT">
 *
 * @author Johnny Human <https://github.com/johnnyhuman>
 * @license Dual licensed under the MIT and GPL licenses
 *
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 **/

(function($){
    $.fn.clabel = function(options) {
        var defaults = {
            class:         "clabel-set",
            class_focus:   "",
            strip_garbage: true
        };

        var options = $.extend(defaults, options);

        return this.each(function() {
            var label = $('label[for=' + $(this).attr('id') + ']').text();

            if (options.strip_garbage) {
            	label = label.replace(/[\:]/g, "");
            	label = $.trim(label);
            }

            $('label[for=' + $(this).attr('id') + ']').remove();

            $(this).addClass(options.class);
            $(this).val(label);

            $($(this)).unbind().bind("blur focus", function() {
                if ($(this).hasClass(options.class)) {
                    $(this).val("");
                    $(this).removeClass(options.class);
                } else if ($(this).val() == "") {
                    $(this).addClass(options.class);
                    $(this).val(label);
                }
            });
        });
    };
})(jQuery);
<|endoftext|>