Explorar o código

Validate Block Name (#8538)

* validation the name that the user inputs on node blocks. If it is a reserved word throw, up an error pop up

* fixing merge

* fixing bug relating to object not redendering

* fixing styling

* added validator to textinputlinecomponent

* reverting file

* fixing linting error, and attempt to revert committed file

* fixing linting
Pamela W %!s(int64=5) %!d(string=hai) anos
pai
achega
70e5d8ffac

+ 8 - 1
nodeEditor/src/diagram/properties/genericNodePropertyComponent.tsx

@@ -39,7 +39,14 @@ export class GeneralPropertyTabComponent extends React.Component<IPropertyCompon
                     {
                         (!this.props.block.isInput || !(this.props.block as InputBlock).isAttribute) &&
                         <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.block}
-                            onChange={() => this.props.globalState.onUpdateRequiredObservable.notifyObservers()} />
+                            onChange={() => this.props.globalState.onUpdateRequiredObservable.notifyObservers()}
+                            validator={ newName => 
+                            {if(!this.props.block.validateBlockName(newName)){ 
+                                this.props.globalState.onErrorMessageDialogRequiredObservable.notifyObservers(`"${newName}" is a reserved name, please choose another`);
+                                return false;
+                            }
+                            return true;
+                            }} />
                     }
                     <TextLineComponent label="Type" value={this.props.block.getClassName()} />
                     <TextInputLineComponent globalState={this.props.globalState} label="Comments" propertyName="comments" target={this.props.block}

+ 8 - 0
nodeEditor/src/sharedComponents/textInputLineComponent.tsx

@@ -10,6 +10,7 @@ interface ITextInputLineComponentProps {
     propertyName?: string;
     value?: string;
     onChange?: (value: string) => void;
+    validator?: (value: string) => boolean;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
@@ -58,6 +59,13 @@ export class TextInputLineComponent extends React.Component<ITextInputLineCompon
 
         this._localChange = true;
         const store = this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!];
+
+        if(this.props.validator && raisePropertyChanged) {
+            if(this.props.validator(value) == false) {
+                value = store;
+            }
+        }
+
         this.setState({ value: value });
 
         if (raisePropertyChanged) {

+ 15 - 2
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -178,6 +178,18 @@ export class InputBlock extends NodeMaterialBlock {
     }
 
     /**
+    * Validates if a name is a reserve word.
+    * @param newName the new name to be given to the node.
+    * @returns false if the name is a reserve word, else true.
+    */
+    public validateBlockName(newName: string) {
+        if (!this.isAttribute) {
+            return super.validateBlockName(newName);
+        }
+        return true;
+    }
+
+    /**
      * Gets the output component
      */
     public get output(): NodeMaterialConnectionPoint {
@@ -190,10 +202,10 @@ export class InputBlock extends NodeMaterialBlock {
      * @returns the current connection point
      */
     public setAsAttribute(attributeName?: string): InputBlock {
+        this._mode = NodeMaterialBlockConnectionPointMode.Attribute;
         if (attributeName) {
             this.name = attributeName;
         }
-        this._mode = NodeMaterialBlockConnectionPointMode.Attribute;
         return this;
     }
 
@@ -709,10 +721,11 @@ export class InputBlock extends NodeMaterialBlock {
     }
 
     public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        this._mode = serializationObject.mode;
         super._deserialize(serializationObject, scene, rootUrl);
 
         this._type = serializationObject.type;
-        this._mode = serializationObject.mode;
+
         this._systemValue = serializationObject.systemValue || serializationObject.wellKnownValue;
         this._animationType = serializationObject.animationType;
         this.visibleInInspector = serializationObject.visibleInInspector;

+ 48 - 4
src/Materials/Node/nodeMaterialBlock.ts

@@ -23,6 +23,7 @@ export class NodeMaterialBlock {
     private _target: NodeMaterialBlockTargets;
     private _isFinalMerger = false;
     private _isInput = false;
+    private _name = "";
     protected _isUnique = false;
 
     /** Gets or sets a boolean indicating that only one input can be connected at a time */
@@ -40,9 +41,22 @@ export class NodeMaterialBlock {
     public _preparationId: number;
 
     /**
-     * Gets or sets the name of the block
+     * Gets the name of the block
      */
-    public name: string;
+    public get name(): string {
+         return this._name;
+    }
+
+    /**
+     * Sets the name of the block. Will check if the name is valid.
+     */
+    public set name(newName: string) {
+        if (!this.validateBlockName(newName)) {
+            return;
+        }
+
+        this._name = newName;
+    }
 
     /**
      * Gets or sets the unique id of the node
@@ -150,12 +164,11 @@ export class NodeMaterialBlock {
      * @param isInput defines a boolean indicating that this block is an input (e.g. it sends data to the shader). Default is false
      */
     public constructor(name: string, target = NodeMaterialBlockTargets.Vertex, isFinalMerger = false, isInput = false) {
-        this.name = name;
 
         this._target = target;
-
         this._isFinalMerger = isFinalMerger;
         this._isInput = isInput;
+        this._name = name;
         this.uniqueId = UniqueIdGenerator.UniqueId;
     }
 
@@ -439,6 +452,37 @@ export class NodeMaterialBlock {
     }
 
     /**
+    * Validates the new name for the block node.
+    * @param newName the new name to be given to the node.
+    * @returns false if the name is a reserve word, else true.
+    */
+    public validateBlockName(newName: string) {
+        let reservedNames: Array<string> = [
+        "position",
+        "normal",
+        "tangent",
+        "particle_positionw",
+        "uv",
+        "uv2",
+        "position2d",
+        "particle_uv",
+        "matricesIndices",
+        "matricesWeights",
+        "world0",
+        "world1",
+        "world2",
+        "world3",
+        "particle_color",
+        "particle_texturemask"];
+        for (var reservedName of reservedNames) {
+            if (newName === reservedName) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
      * Compile the current node and generate the shader code
      * @param state defines the current compilation state (uniforms, samplers, current string)
      * @param activeBlocks defines the list of active blocks (i.e. blocks to compile)