123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /**
- * @license Licensed under the Apache License, Version 2.0 (the "License"):
- * http://www.apache.org/licenses/LICENSE-2.0
- */
- /**
- * @fileoverview Utility functions for handling Instances.
- */
- 'use strict';
- goog.provide('Blockly.Instances');
- goog.require('Blockly.Workspace');
- goog.require('goog.string');
- /**
- * Category to separate instance names from instances, procedures and
- * generated functions.
- */
- Blockly.Instances.NAME_TYPE = 'INSTANCE';
- /**
- * Find all user-created instances.
- * @param {?string}
- * @param {!Blockly.Workspace} workspace Workspace to transverse for instances.
- * @return {!Array.<string>} Array of instance names.
- */
- Blockly.Instances.allInstancesOf = function(instanceType, workspace) {
- var blocks;
- if (workspace.getAllBlocks) {
- blocks = workspace.getAllBlocks();
- } else {
- throw 'Not a valid Workspace: ' + workspace;
- }
- var instanceHash = Object.create(null);
- // Iterate through every block and add each instance to the hash.
- for (var i = 0; i < blocks.length; i++) {
- var blockInstances = blocks[i].getInstances(instanceType);
- for (var j = 0; j < blockInstances.length; j++) {
- var instanceName = blockInstances[j];
- // Instance name may be null if the block is only half-built.
- if (instanceName) {
- instanceHash[instanceName.toLowerCase()] = instanceName;
- }
- }
- }
- // Flatten the hash into a list.
- var instanceList = [];
- for (var name in instanceHash) {
- instanceList.push(instanceHash[name]);
- }
- return instanceList;
- };
- /** Returns all instances of all types. */
- Blockly.Instances.allInstances = function(workspace) {
- return Blockly.Instances.allInstancesOf(undefined, workspace);
- };
- /** Returns the first Instance name of a given type. */
- Blockly.Instances.getAnyInstanceOf = function(instanceType, workspace) {
- var blocks;
- if (workspace.getAllBlocks) {
- blocks = workspace.getAllBlocks();
- } else {
- throw 'Not a valid Workspace: ' + workspace;
- }
- for (var i = 0; i < blocks.length; i++) {
- var blockInstances = blocks[i].getInstances(instanceType);
- if (blockInstances.length) {
- return blockInstances[0];
- }
- }
- };
- /** Indicates if the given instance is present in the workspace. */
- Blockly.Instances.isInstancePresent = function(
- instanceName, instanceType, block) {
- var blocks;
- if (block.workspace && block.workspace.getAllBlocks) {
- blocks = block.workspace.getAllBlocks();
- } else {
- throw 'Not a valid block: ' + block;
- }
- for (var i = 0; i < blocks.length; i++) {
- var blockInstances = blocks[i].getInstances(instanceType);
- for (var j = 0; j < blockInstances.length; j++) {
- if ((blockInstances[j] === instanceName) && (blocks[i] !== block)) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * Find all instances of the specified name and type and rename them.
- * @param {string} oldName Instance to rename.
- * @param {string} newName New Instance name.
- * @param {!Blockly.Workspace} workspace Workspace rename instances in.
- */
- Blockly.Instances.renameInstance = function(
- oldName, newName, instanceType, workspace) {
- Blockly.Events.setGroup(true);
- var blocks = workspace.getAllBlocks();
- // Iterate through every block.
- for (var i = 0; i < blocks.length; i++) {
- blocks[i].renameInstance(oldName, newName, instanceType);
- }
- Blockly.Events.setGroup(false);
- };
- /**
- * Return a new instance name that is not yet being used as an instance or as a
- * variable name. This will try to generate single letter names in the range
- * 'i' to 'z' to start with.
- * If no unique name is located it will try 'i' to 'z', 'a' to 'h',
- * then 'i2' to 'z2' etc. Skip 'l'.
- * @param {!Blockly.Workspace} workspace The workspace to be unique in.
- * @return {string} New instance name.
- */
- Blockly.Instances.generateUniqueName = function(workspace) {
- var combinedList = Blockly.Variables.allVariables(workspace).concat(
- Blockly.Instances.allInstances(workspace));
- var newName = '';
- if (combinedList.length) {
- var nameSuffix = 1;
- var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
- var letterIndex = 0;
- var potName = letters.charAt(letterIndex);
- while (!newName) {
- var inUse = false;
- for (var i = 0; i < combinedList.length; i++) {
- if (combinedList[i].toLowerCase() == potName) {
- // This potential name is already used.
- inUse = true;
- break;
- }
- }
- if (inUse) {
- // Try the next potential name.
- letterIndex++;
- if (letterIndex == letters.length) {
- // Reached the end of the character sequence so back to 'i'.
- // a new suffix.
- letterIndex = 0;
- nameSuffix++;
- }
- potName = letters.charAt(letterIndex);
- if (nameSuffix > 1) {
- potName += nameSuffix;
- }
- } else {
- // We can use the current potential name.
- newName = potName;
- }
- }
- } else {
- newName = 'i';
- }
- return newName;
- };
- /**
- * Return a version of the instance name that has not yet been used.
- * It does so by adding a number at the end of the name.
- * @param {string} instanceName Instance name to make unique.
- * @param {!Blockly.Workspace|Blockly.Block} workspace The workspace to be unique in.
- * @return {string} Unique instance name based on name input.
- */
- Blockly.Instances.convertToUniqueName = function(instanceName, workspace) {
- var combinedList = Blockly.Variables.allVariables(workspace).concat(
- Blockly.Instances.allInstances(workspace));
- return Blockly.Instances.appendToName_(instanceName, combinedList);
- };
- /** */
- Blockly.Instances.convertToUniqueNameBlock = function(instanceName, block) {
- var blocks;
- if (block.workspace) {
- blocks = block.workspace.getAllBlocks();
- } else {
- throw 'Not a valid Workspace: ' + workspace;
- }
- var instanceHash = Object.create(null);
- // Iterate through every block and add each instance to the hash.
- for (var i = 0; i < blocks.length; i++) {
- // Do not add to the list this block instance
- if (blocks[i] !== block) {
- var blockInstances = blocks[i].getInstances();
- for (var j = 0; j < blockInstances.length; j++) {
- var blockInstanceName = blockInstances[j];
- // Instance name may be null if the block is only half-built.
- if (blockInstanceName) {
- instanceHash[blockInstanceName.toLowerCase()] = blockInstanceName;
- }
- }
- }
- }
- // Flatten the hash into a list.
- var instanceList = [];
- for (var name in instanceHash) {
- instanceList.push(instanceHash[name]);
- }
- var combinedList = Blockly.Variables.allVariables(block.workspace).concat(
- instanceList);
- return Blockly.Instances.appendToName_(instanceName, combinedList);
- };
- /** */
- Blockly.Instances.appendToName_ = function(instanceName, nameList) {
- if (!instanceName) {
- return Blockly.Instances.generateUniqueName(workspace);
- } else {
- var newName = instanceName;
- var nameSuffix = 2;
- if (instanceName.match(/_\d+$/)) {
- // instanceName ends with and underscore and a number, so increase count
- var instanceNameSuffix = instanceName.match(/\d+$/)[0];
- instanceName = instanceName.slice(
- 0, (instanceNameSuffix.length * -1) - 1);
- nameSuffix = parseInt(instanceNameSuffix, 10) + 1;
- newName = instanceName + '_' + nameSuffix;
- }
- while (nameList.indexOf(newName) !== -1) {
- newName = instanceName + '_' + nameSuffix++;
- }
- return newName;
- }
- };
|