/*
* Copyright 2010 Jean-Paul Balabanian and Yngve Devik Hammersland
*
* This file is part of glsl4idea.
*
* Glsl4idea is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Glsl4idea is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with glsl4idea. If not, see <http://www.gnu.org/licenses/>.
*/
package glslplugin.lang.elements.types;
import glslplugin.lang.elements.types.constructors.GLSLBasicConstructorType;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
/**
* Scalar type is a type that has only magnitude, no members or elements.
* NOTE: Although practically, they have one member - themselves.
*
* @author Yngve Devik Hammersland
* @author Jan Polák
*/
public class GLSLScalarType extends GLSLType {
//region Static
public static final GLSLScalarType BOOL = new GLSLScalarType("bool", Boolean.class);
public static final GLSLScalarType DOUBLE = new GLSLScalarType("double", Double.class);
public static final GLSLScalarType FLOAT = new GLSLScalarType("float", Double.class, DOUBLE);
public static final GLSLScalarType UINT = new GLSLScalarType("uint", Long.class, FLOAT, DOUBLE);
public static final GLSLScalarType INT = new GLSLScalarType("int", Long.class, UINT, FLOAT, DOUBLE);
private static final GLSLScalarType[] SCALARS = {BOOL, DOUBLE, FLOAT, UINT, INT};
public static boolean isIntegerScalar(GLSLType type){
return type == INT || type == UINT;
}
//endregion
private final String typename;
private final Collection<GLSLType> implicitConversions;
private GLSLScalarType(String typename, Class<?> javaType, GLSLType... implicitlyConvertibleTo) {
super(javaType);
this.typename = typename;
this.implicitConversions = Arrays.asList(implicitlyConvertibleTo);
}
@NotNull
public String getTypename() {
return typename;
}
public boolean typeEquals(GLSLType otherType) {
return this == otherType;
}
public boolean isConvertibleTo(GLSLType otherType) {
return otherType.isValidType() &&
(typeEquals(otherType) || implicitConversions.contains(otherType));
}
@Override
public boolean hasMembers() {
//Scalars do have members like vectors, but no .length() and no indexing
return true;
}
@Override
public boolean hasMember(String member) {
//Only members of scalars are first vector components
//Scalars are basically one-component-vectors in this regard
return member.length() == 1 && "xrs".indexOf(member.charAt(0)) != -1;
}
@NotNull
@Override
public GLSLType getMemberType(String member) {
if(hasMember(member)){
return this;
}else{
return GLSLTypes.UNKNOWN_TYPE;
}
}
private GLSLFunctionType[] constructorsCache;
/**
* Each scalar type is explicitly convertible to any other scalar type.
* See 5.4.1 of GLSL Spec. 4.50
*/
@NotNull
@Override
public GLSLFunctionType[] getConstructors() {
if(constructorsCache == null){
final GLSLFunctionType[] constructorsCache = this.constructorsCache = new GLSLFunctionType[SCALARS.length];
for (int i = 0; i < SCALARS.length; i++) {
constructorsCache[i] = new GLSLBasicConstructorType(this, SCALARS[i]);
}
}
return constructorsCache;
}
@Override
public String toString() {
return "Primitive Type: " + getTypename();
}
}