void JSONValue::WriteIndent(String& dest, int indent) { uint oldLength = dest.Length(); dest.Resize(oldLength + indent); for (int i = 0; i < indent; ++i) dest[oldLength + i] = ' '; }
static int Deserializer_Read(duk_context* ctx) { duk_int_t magic = duk_get_current_magic(ctx); duk_push_this(ctx); // safe cast based on type check above Deserializer* deserial = CastToDeserializer(ctx, duk_get_top_index(ctx)); duk_pop(ctx); if (!deserial) { duk_push_boolean(ctx, 0); return 1; } char* data; String str; size_t length; IO_MAGIC_TYPE v = (IO_MAGIC_TYPE) magic; bool success = false; switch(v) { case IO_MAGIC_INT: duk_push_number(ctx, (double) deserial->ReadInt()); return 1; case IO_MAGIC_STRING: length = deserial->GetSize() - deserial->GetPosition(); str.Resize(length + 1); deserial->Read(&str[0], length); str[length] = '\0'; duk_push_string(ctx, str.CString()); return 1; case IO_MAGIC_ZEROSTRING: success = duk_push_string(ctx, deserial->ReadString().CString()); return 1; case IO_MAGIC_BINARY: length = deserial->GetSize() - deserial->GetPosition(); duk_push_fixed_buffer(ctx, length); duk_push_buffer_object(ctx, -1, 0, length, DUK_BUFOBJ_UINT8ARRAY); duk_replace(ctx, -2); data = (char*) duk_require_buffer_data(ctx, 0, &length); success = deserial->Read(data, length); return 1; default: break; } duk_push_undefined(ctx); return 1; }
String Scene::GetVarNamesAttr() const { String ret; if (!varNames_.Empty()) { for (HashMap<StringHash, String>::ConstIterator i = varNames_.Begin(); i != varNames_.End(); ++i) ret += i->second_ + ';'; ret.Resize(ret.Length() - 1); } return ret; }
void BufferToString(String& dest, const void* data, unsigned size) { // Precalculate needed string size const unsigned char* bytes = (const unsigned char*)data; unsigned length = 0; for (unsigned i = 0; i < size; ++i) { // Room for separator if (i) ++length; // Room for the value if (bytes[i] < 10) ++length; else if (bytes[i] < 100) length += 2; else length += 3; } dest.Resize(length); unsigned index = 0; // Convert values for (unsigned i = 0; i < size; ++i) { if (i) dest[index++] = ' '; if (bytes[i] < 10) { dest[index++] = '0' + bytes[i]; } else if (bytes[i] < 100) { dest[index++] = (char)('0' + bytes[i] / 10); dest[index++] = (char)('0' + bytes[i] % 10); } else { dest[index++] = (char)('0' + bytes[i] / 100); dest[index++] = (char)('0' + bytes[i] % 100 / 10); dest[index++] = (char)('0' + bytes[i] % 10); } } }
static String GenerateNameFromType(StringHash typeHash) { if (unknownTypeToName.Contains(typeHash)) return unknownTypeToName[typeHash]; String test; // Begin brute-force search unsigned numLetters = letters.Length(); unsigned combinations = numLetters; bool found = false; for (unsigned i = 1; i < 6; ++i) { test.Resize(i); for (unsigned j = 0; j < combinations; ++j) { unsigned current = j; for (unsigned k = 0; k < i; ++k) { test[k] = letters[current % numLetters]; current /= numLetters; } if (StringHash(test) == typeHash) { found = true; break; } } if (found) break; combinations *= numLetters; } unknownTypeToName[typeHash] = test; return test; }
bool ShaderProgram::Link() { PROFILE(LinkShaderProgram); Release(); if (!graphics || !graphics->IsInitialized()) { LOGERROR("Can not link shader program without initialized Graphics subsystem"); return false; } if (!vs || !ps) { LOGERROR("Shader(s) are null, can not link shader program"); return false; } if (!vs->GLShader() || !ps->GLShader()) { LOGERROR("Shaders have not been compiled, can not link shader program"); return false; } const String& vsSourceCode = vs->Parent() ? vs->Parent()->SourceCode() : String::EMPTY; const String& psSourceCode = ps->Parent() ? ps->Parent()->SourceCode() : String::EMPTY; program = glCreateProgram(); if (!program) { LOGERROR("Could not create shader program"); return false; } glAttachShader(program, vs->GLShader()); glAttachShader(program, ps->GLShader()); glLinkProgram(program); int linked; glGetProgramiv(program, GL_LINK_STATUS, &linked); if (!linked) { int length, outLength; String errorString; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); errorString.Resize(length); glGetProgramInfoLog(program, length, &outLength, &errorString[0]); glDeleteProgram(program); program = 0; LOGERRORF("Could not link shaders %s: %s", FullName().CString(), errorString.CString()); return false; } LOGDEBUGF("Linked shaders %s", FullName().CString()); glUseProgram(program); char nameBuffer[MAX_NAME_LENGTH]; int numAttributes, numUniforms, numUniformBlocks, nameLength, numElements; GLenum type; attributes.Clear(); glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes); for (int i = 0; i < numAttributes; ++i) { glGetActiveAttrib(program, i, (GLsizei)MAX_NAME_LENGTH, &nameLength, &numElements, &type, nameBuffer); VertexAttribute newAttribute; newAttribute.name = String(nameBuffer, nameLength); newAttribute.semantic = SEM_POSITION; newAttribute.index = 0; for (size_t j = 0; elementSemanticNames[j]; ++j) { if (newAttribute.name.StartsWith(elementSemanticNames[j], false)) { int index = NumberPostfix(newAttribute.name); if (index >= 0) newAttribute.index = (unsigned char)index; break; } newAttribute.semantic = (ElementSemantic)(newAttribute.semantic + 1); } if (newAttribute.semantic == MAX_ELEMENT_SEMANTICS) { LOGWARNINGF("Found vertex attribute %s with no known semantic in shader program %s", newAttribute.name.CString(), FullName().CString()); continue; } newAttribute.location = glGetAttribLocation(program, newAttribute.name.CString()); attributes.Push(newAttribute); } glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms); int numTextures = 0; for (int i = 0; i < numUniforms; ++i) { glGetActiveUniform(program, i, MAX_NAME_LENGTH, &nameLength, &numElements, &type, nameBuffer); String name(nameBuffer, nameLength); if (type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_SHADOW) { // Assign sampler uniforms to a texture unit according to the number appended to the sampler name int location = glGetUniformLocation(program, name.CString()); int unit = NumberPostfix(name); // If no unit number specified, assign in appearance order starting from unit 0 if (unit < 0) unit = numTextures; // Array samplers may have multiple elements, assign each sequentially if (numElements > 1) { Vector<int> units; for (int j = 0; j < numElements; ++j) units.Push(unit++); glUniform1iv(location, numElements, &units[0]); } else glUniform1iv(location, 1, &unit); numTextures += numElements; } } glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); for (int i = 0; i < numUniformBlocks; ++i) { glGetActiveUniformBlockName(program, i, (GLsizei)MAX_NAME_LENGTH, &nameLength, nameBuffer); // Determine whether uniform block belongs to vertex or pixel shader String name(nameBuffer, nameLength); bool foundVs = vsSourceCode.Contains(name); bool foundPs = psSourceCode.Contains(name); if (foundVs && foundPs) { LOGWARNINGF("Found uniform block %s in both vertex and pixel shader in shader program %s"); continue; } // Vertex shader constant buffer bindings occupy slots starting from zero to maximum supported, pixel shader bindings // from that point onward unsigned blockIndex = glGetUniformBlockIndex(program, name.CString()); int bindingIndex = NumberPostfix(name); // If no number postfix in the name, use the block index if (bindingIndex < 0) bindingIndex = blockIndex; if (foundPs) bindingIndex += (unsigned)graphics->NumVSConstantBuffers(); glUniformBlockBinding(program, blockIndex, bindingIndex); } return true; }