void lualoom_pushnative_userdata(lua_State *L, Type *type, int nativeIdx) { nativeIdx = lua_absindex(L, nativeIdx); lmAssert(lua_isuserdata(L, nativeIdx), "Internal Error: userdata expected in lsr_instancewrapnative"); if (type->isNativeManaged()) { lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMANAGEDNATIVESCRIPT); lua_pushvalue(L, nativeIdx); lua_gettable(L, -2); lmAssert(lua_istable(L, -1), "Internal Error: Unable to get managed native for return value"); lua_remove(L, -2); // remove managed table return; } nativeIdx = lua_absindex(L, nativeIdx); lua_newtable(L); int instanceIdx = lua_gettop(L); lsr_getclasstable(L, type); lua_rawseti(L, instanceIdx, LSINDEXCLASS); lua_pushlightuserdata(L, type); lua_rawseti(L, instanceIdx, LSINDEXTYPE); lua_pushvalue(L, nativeIdx); lua_rawseti(L, instanceIdx, LSINDEXNATIVE); // set meta table luaL_getmetatable(L, LSINSTANCE); lua_setmetatable(L, instanceIdx); }
Assembly *LSLuaState::loadExecutableAssemblyBinary(const char *buffer, long bufferSize) { Assembly *assembly = NULL; utByteArray headerBytes; headerBytes.allocateAndCopy((void *)buffer, sizeof(unsigned int) * 4); // we need to decompress lmAssert(headerBytes.readUnsignedInt() == LOOM_BINARY_ID, "binary id mismatch"); lmAssert(headerBytes.readUnsignedInt() == LOOM_BINARY_VERSION_MAJOR, "major version mismatch"); lmAssert(headerBytes.readUnsignedInt() == LOOM_BINARY_VERSION_MINOR, "minor version mismatch"); unsigned int sz = headerBytes.readUnsignedInt(); utByteArray bytes; bytes.resize(sz); uLongf readSZ = sz; int ok = uncompress((Bytef *)bytes.getDataPtr(), (uLongf *)&readSZ, (const Bytef *)((unsigned char *)buffer + sizeof(unsigned int) * 4), (uLong)sz); lmAssert(ok == Z_OK, "problem uncompressing executable assembly"); lmAssert(readSZ == sz, "Read size mismatch"); assembly = loadAssemblyBinary(&bytes); return assembly; }
Assembly *LSLuaState::loadExecutableAssembly(const utString& assemblyName, bool absPath) { // executables always in bin utString filePath; if (!absPath) { filePath = "./bin/"; } filePath += assemblyName; if (!strstr(filePath.c_str(), ".loom")) { filePath += ".loom"; } const char *buffer = NULL; long bufferSize; LSMapFile(filePath.c_str(), (void **)&buffer, &bufferSize); lmAssert(buffer && bufferSize, "Error loading executable: %s, unable to map file", assemblyName.c_str()); Assembly* assembly = loadExecutableAssemblyBinary(buffer, bufferSize); LSUnmapFile(filePath.c_str()); lmAssert(assembly, "Error loading executable: %s", assemblyName.c_str()); assembly->freeByteCode(); return assembly; }
void LoomProfiler::validate() { for (LoomProfilerRoot *walk = LoomProfilerRoot::sRootList; walk; walk = walk->mNextRoot) { for (LoomProfilerEntry *dp = walk->mFirstLoomProfilerEntry; dp; dp = dp->mNextForRoot) { lmAssert(dp->mRoot == walk, "Mismatch"); // check if it's in the parent's list... LoomProfilerEntry *wk; for (wk = dp->mParent->mFirstChild; wk; wk = wk->mNextSibling) { if (wk == dp) { break; } } lmAssert(wk, "Validation failed - couldnot find child in its parent's list."); for (wk = dp->mParent->mChildHash[walk->mNameHash & (LoomProfilerEntry::HashTableSize - 1)]; wk; wk = wk->mNextHash) { if (wk == dp) { break; } } lmAssert(wk, "Valdation failed- couldn't find child in its parent's hash."); } } }
// only called when table index does not exist static int lsr_instancenewindex(lua_State *L) { if (!lua_isnumber(L, 2)) { lua_rawset(L, 1); return 0; } lua_rawgeti(L, 1, LSINDEXTYPE); Type *type = (Type *)lua_topointer(L, -1); lua_pop(L, 1); lmAssert(type, "Missing type on instance new index"); int ordinal = (int)lua_tonumber(L, 2); // a loom indexer should be in the table (not missing so it his the index metamethod) lmAssert(!lualoom_isindexer(ordinal), "Internal Error: instance table being indexed by a LSINDEX value."); if (!type->isNativeOrdinal(ordinal)) { lua_rawset(L, 1); return 0; } else { lua_rawgeti(L, 1, LSINDEXNATIVE); lua_replace(L, 1); lua_settable(L, 1); } return 0; }
void *loom_asset_lock(const char *name, unsigned int type, int block) { const char *namePtr = stringtable_insert(name); loom_mutex_lock(gAssetLock); // Look it up. loom_asset_t *asset = loom_asset_getAssetByName(namePtr, 1); lmAssert(asset != NULL, "Didn't get asset even though we should have!"); // If not loaded, and we aren't ready to block, return NULL. if ((block == 0) && (asset->state != loom_asset_t::Loaded)) { lmLogDebug(gAssetLogGroup, "Not blocking and not loaded yet; lock of '%s' failed.", namePtr); loom_mutex_unlock(gAssetLock); return NULL; } // Otherwise, let's force it to load now. if (asset->state != loom_asset_t::Loaded) { lmLogDebug(gAssetLogGroup, "Blocking so forcing load of '%s'.", namePtr); loom_asset_preload(namePtr); lmAssert(loom_asset_isOnTrackToLoad(asset), "Preloaded but wasn't on track to load!"); while (loom_asset_checkLoadedPercentage(namePtr) != 1.f && loom_asset_isOnTrackToLoad(asset)) { lmLogDebug(gAssetLogGroup, "Pumping load of '%s'...", namePtr); loom_asset_pump(); } if (asset->state != loom_asset_t::Loaded) { lmLogError(gAssetLogGroup, "Unable to load asset '%s'!", name); loom_mutex_unlock(gAssetLock); return NULL; } } // Check type. if (asset->type != type) { lmLogError(gAssetLogGroup, "Tried to lock asset '%s' with wrong type, assetType=%x, requestedType=%x", name, asset->type, type); loom_mutex_unlock(gAssetLock); return NULL; } // Inc count. asset->blob->incRef(); loom_mutex_unlock(gAssetLock); lmLogDebug(gAssetLogGroup, "Locked asset '%s'...", namePtr); // Return ptr. return asset->blob->bits; }
void LSCompiler::processLoomConfig() { utArray<unsigned char> configBytes; json_t *json = NULL; if (utFileStream::tryReadToArray("./loom.config", configBytes, true)) { if (configBytes.size()) { json_error_t error; json = json_loads((const char *)configBytes.ptr(), JSON_DISABLE_EOF_CHECK, &error); lmAssert(json, "JSON Error: Line %i Column %i Position %i, %s (Source: %s)", error.line, error.column, error.position, error.text, "./loom.config"); } } // if we don't have a loom.config or it is empty, initial empty json config if (!json) { json = json_object(); } // add default addSourcePath("./src"); json_t *classpath = json_object_get(json, "classpath"); if (classpath) { lmAssert(json_is_array(classpath), "malformed classpath array in loom.config JSON"); // if we have a classpath array, no default sourcePath.clear(); for (size_t i = 0; i < json_array_size(classpath); i++) { json_t *path = json_array_get(classpath, i); lmAssert(json_is_string(path), "non-string in classpath array in loom.config JSON"); const char *spath = json_string_value(path); if (loomConfigClassPath.find(spath) != UT_NPOS) { lmAssert(0, "duplicate path in classpath array in loom.config JSON"); } loomConfigClassPath.push_back(spath); addSourcePath(spath); } } // and store to static var loomConfigJSON = json; }
void LSCompiler::processExecutableConfig(AssemblyBuilder *ab) { lmAssert(loomConfigJSON, "loomConfigJSON not initialized"); utHashTable<utHashedString, utString> defs; for (UTsize i = 0; i < LSLuaState::getNumCommandlineArgs(); i++) { const char *arg = LSLuaState::getCommandlineArg(i).c_str(); if ((strlen(arg) >= 3) && (arg[0] == '-') && (arg[1] == 'D')) { char key[1024]; char value[1024]; lmAssert(strlen(arg) < 1023, "argument buffer overflow"); key[0] = value[0] = 0; strcpy(key, &arg[2]); if (strstr(arg, "=")) { key[strstr(arg, "=") - arg - 2] = 0; strcpy(value, strstr(arg, "=") + 1); } // value defaults to true if (!value[0]) { sprintf(value, "true"); } defs.insert(key, value); } } // Add command line defines to config json_t *json = json_deep_copy(loomConfigJSON); utHashTable<utHashedString, utString>::Iterator itr = defs.iterator(); while (itr.hasMoreElements()) { const char *key = itr.peekNextKey().str().c_str(); const char *value = itr.peekNextValue().c_str(); json_object_set_new(json, key, json_string(value)); itr.next(); } const char *out = json_dumps(json, JSON_INDENT(3) | JSON_COMPACT); ab->setLoomConfig(out); }
VertexPosColorTex *QuadRenderer::getQuadVertexMemory(uint16_t vertexCount, TextureID texture, bool blendEnabled, uint32_t srcBlend, uint32_t dstBlend, ShaderProgram *shader) { LOOM_PROFILE_SCOPE(quadGetVertices); if (!vertexCount || (texture < 0) || (vertexCount > MAXBATCHQUADS * 4) || shader == nullptr) { return NULL; } #ifdef LOOM_DEBUG loom_mutex_lock(Texture::sTexInfoLock); lmAssert(!(vertexCount % 4), "numVertices % 4 != 0"); lmAssert(texture == Texture::getTextureInfo(texture)->id, "Texture ID signature mismatch, you might be trying to draw a disposed texture"); loom_mutex_unlock(Texture::sTexInfoLock); lmAssert(batchedVertices, "batchedVertices should not be null"); #endif bool doSubmit = false; if (currentTexture != TEXTUREINVALID && currentTexture != texture) doSubmit = true; if (sCurrentShader != NULL && *sCurrentShader != *shader) doSubmit = true; if (srcBlend != sSrcBlend || dstBlend != sDstBlend) doSubmit = true; if ((batchedVertexCount + vertexCount) > MAXBATCHQUADS * 4) doSubmit = true; if (doSubmit) submit(); if (currentTexture != TEXTUREINVALID && currentTexture != texture) sTextureStateValid = false; if (sCurrentShader != NULL && *sCurrentShader != *shader) sShaderStateValid = false; if (srcBlend != sSrcBlend || dstBlend != sDstBlend || blendEnabled != sBlendEnabled) sBlendStateValid = false; sSrcBlend = srcBlend; sDstBlend = dstBlend; sBlendEnabled = blendEnabled; currentTexture = texture; sCurrentShader = shader; VertexPosColorTex *currentVertices = &batchedVertices[batchedVertexCount]; batchedVertexCount += vertexCount; return currentVertices; }
void NativeDelegate::assertMainThread() { lmAssert(smMainThreadID != scmBadThreadID, "Tried to touch a NativeDelegate before the main thread was marked. " "Probably need to add a markMainThread call?"); lmAssert(platform_getCurrentThreadId() == smMainThreadID, "Trying to fire a NativeDelegate from thread %x that is not the main " "thread %x. This will result in memory corruption and race conditions!", platform_getCurrentThreadId(), smMainThreadID); }
void LoomProfiler::hashPop(LoomProfilerRoot *expected) { mStackDepth--; lmAssert(mStackDepth >= 0, "Stack underflow in profiler. You may have mismatched PROFILE_START and PROFILE_ENDs"); if (mEnabled) { if (mCurrentLoomProfilerEntry->mSubDepth) { mCurrentLoomProfilerEntry->mSubDepth--; return; } if (expected) { lmAssert(expected == mCurrentLoomProfilerEntry->mRoot, "LoomProfiler::hashPop - didn't get expected ProfilerRoot!"); } F64 fElapsed = endHighResolutionTimer(mCurrentLoomProfilerEntry->mStartTime); lmAssert(fElapsed > 0, "Elapsed time should be positive!"); mCurrentLoomProfilerEntry->mTotalTime += fElapsed; mCurrentLoomProfilerEntry->mParent->mSubTime += fElapsed; // mark it in the parent as well... mCurrentLoomProfilerEntry->mRoot->mTotalTime += fElapsed; mCurrentLoomProfilerEntry->mMaxTime = fElapsed > mCurrentLoomProfilerEntry->mMaxTime ? fElapsed : mCurrentLoomProfilerEntry->mMaxTime; mCurrentLoomProfilerEntry->mMinTime = fElapsed < mCurrentLoomProfilerEntry->mMinTime ? fElapsed : mCurrentLoomProfilerEntry->mMinTime; mCurrentLoomProfilerEntry->mRoot->mMaxTime = fElapsed > mCurrentLoomProfilerEntry->mRoot->mMaxTime ? fElapsed : mCurrentLoomProfilerEntry->mRoot->mMaxTime; mCurrentLoomProfilerEntry->mRoot->mMinTime = fElapsed < mCurrentLoomProfilerEntry->mRoot->mMinTime ? fElapsed : mCurrentLoomProfilerEntry->mRoot->mMinTime; if (mCurrentLoomProfilerEntry->mParent->mRoot) { mCurrentLoomProfilerEntry->mParent->mRoot->mSubTime += fElapsed; // mark it in the parent as well... } mCurrentLoomProfilerEntry = mCurrentLoomProfilerEntry->mParent; } if (mStackDepth == 0) { // apply the next enable... if (mDumpToConsole) { dump(); startHighResolutionTimer(mCurrentLoomProfilerEntry->mStartTime); } if (!mEnabled && mNextEnable) { startHighResolutionTimer(mCurrentLoomProfilerEntry->mStartTime); } mEnabled = mNextEnable; } }
Expression *TypeCompiler::visit(VariableDeclaration *declaration) { FuncState *fs = cs->fs; // local variable declaration lmAssert(!declaration->classDecl, "local variable declaration belongs to a class"); ExpDesc v; BC::singleVar(cs, &v, declaration->identifier->string.c_str()); Type *dt = declaration->type; MethodInfo *method = NULL; method = (MethodInfo *)dt->findMember("__op_assignment"); //TODO: assignment overload in default args? if (declaration->isParameter) { method = NULL; } if (method) { if (dt->isStruct()) { generateVarDeclStruct(declaration); } else if (dt->isDelegate()) { generateVarDeclDelegate(declaration); } else { error("unexpected __op_assignment on non delegate or struct"); } return declaration; } else { lmAssert(!dt->isDelegate() && !dt->isStruct(), "unexpected delegate/struct"); fs->freereg = fs->nactvar; /* free registers */ declaration->identifier->visitExpression(this); declaration->initializer->visitExpression(this); BC::storeVar(fs, &declaration->identifier->e, &declaration->initializer->e); } return declaration; }
Expression *TypeCompiler::visit(CallExpression *call) { MethodBase *methodBase = call->methodBase; call->function->visitExpression(this); // check whether we're calling a methodbase if (methodBase) { lmAssert(methodBase->isMethod(), "Non-method called"); MethodInfo *method = (MethodInfo *)methodBase; generateCall(&call->function->e, call->arguments, method); call->e = call->function->e; } else { lmAssert(call->function->type, "Untyped call"); // if we're calling a delegate we need to load up the call method if (call->function->type->isDelegate()) { MethodInfo *method = (MethodInfo *)call->function->type->findMember("call"); lmAssert(method, "delegate with no call method"); ExpDesc right; BC::initExpDesc(&right, VKNUM, 0); right.u.nval = method->getOrdinal(); BC::expToNextReg(cs->fs, &call->function->e); BC::expToNextReg(cs->fs, &right); BC::expToVal(cs->fs, &right); BC::indexed(cs->fs, &call->function->e, &right); generateCall(&call->function->e, call->arguments, NULL); call->e = call->function->e; } else { // we're directly calling a local, instance (bound), or static method of type Function generateCall(&call->function->e, call->arguments, NULL); call->e = call->function->e; } } return call; }
Expression *TypeCompiler::visit(ConditionalExpression *conditional) { FuncState *fs = cs->fs; int flist; int escapelist = NO_JUMP; int reg = fs->freereg; Expression *expr = conditional->expression; Expression *trueExpr = conditional->trueExpression; Expression *falseExpr = conditional->falseExpression; expr->visitExpression(this); flist = BC::cond(cs, &expr->e); /*true statement*/ BlockCnt bl; enterBlock(fs, &bl, 0); BC::singleVar(cs, &conditional->e, "__ls_ternary"); trueExpr->visitExpression(this); BC::storeVar(fs, &conditional->e, &trueExpr->e); lmAssert(bl.breaklist == NO_JUMP, "Internal Compiler Error"); leaveBlock(fs); fs->freereg = reg; /* false statement*/ BC::concat(fs, &escapelist, BC::jump(fs)); BC::patchToHere(fs, flist); BlockCnt bl2; enterBlock(fs, &bl2, 0); BC::singleVar(cs, &conditional->e, "__ls_ternary"); falseExpr->visitExpression(this); BC::storeVar(fs, &conditional->e, &falseExpr->e); lmAssert(bl.breaklist == NO_JUMP, "Internal Compiler Error"); leaveBlock(fs); BC::patchToHere(fs, escapelist); fs->freereg = reg; BC::singleVar(cs, &conditional->e, "__ls_ternary"); return conditional; }
static void loom_net_setSocketBlocking(loom_socketId_t s, int blocking) { #if LOOM_PLATFORM == LOOM_PLATFORM_WIN32 int blockTmp = blocking ? 0 : 1; int status = ioctlsocket((SOCKET)s, FIONBIO, &blockTmp); lmAssert(status == NO_ERROR, "Failed trying to set socket blocking status due to %d", status); #elif LOOM_PLATFORM_IS_APPLE == 1 || LOOM_PLATFORM == LOOM_PLATFORM_LINUX // This should work for POSIX compliant environments. // See http://stackoverflow.com/questions/1150635/unix-nonblocking-i-o-o-nonblock-vs-fionbio int flags = fcntl((int)s, F_GETFL); if (blocking == 1) { flags &= ~O_NONBLOCK; } else { flags |= O_NONBLOCK; } fcntl((int)s, F_SETFL, flags); #elif LOOM_PLATFORM == LOOM_PLATFORM_ANDROID int val = 1; ioctl((int)s, FIONBIO, &val); #endif }
void TypeCompiler::leaveBlock(FuncState *fs) { BlockCnt *bl = fs->bl; fs->bl = bl->previous; BC::removeVars(fs->cs, bl->nactvar); if (bl->upval) { BC::codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); } /* a block either controls scope or breaks (never both) */ lmAssert(!bl->isbreakable || !bl->upval, "Internal Compiler Error"); lmAssert(bl->nactvar == fs->nactvar, "Internal Compiler Error"); fs->freereg = fs->nactvar; /* free registers */ BC::patchToHere(fs, bl->breaklist); }
void TypeCompiler::generatePropertySet(ExpDesc *call, Expression *value, bool visit) { FuncState *fs = cs->fs; int line = lineNumber; BC::expToNextReg(fs, call); lua_assert(call->k == VNONRELOC); int base = call->u.s.info; /* base register for call */ if (visit) { value->visitExpression(this); BC::expToNextReg(fs, &value->e); } else { BC::reserveRegs(fs, 1); BC::expToReg(fs, &value->e, fs->freereg - 1); } int nparams = fs->freereg - (base + 1); lmAssert(nparams == 1, "nparams != 1"); BC::initExpDesc(call, VCALL, BC::codeABC(fs, OP_CALL, base, nparams + 1, 2)); BC::fixLine(fs, line); fs->freereg = base + 1; }
void Graphics::reset(int width, int height, uint32_t flags) { lmAssert(sInitialized, "Please make sure to call Graphics::initialize first"); lmLogDebug(gGFXLogGroup, "Graphics::reset - %dx%d %x", width, height, flags); // clear context loss state sContextLost = false; Loom2D::Matrix mvp; mvp.scale(2.0f / width, 2.0f / height); mvp.translate(-1.0f, -1.0f); //mvp.copyToMatrix4(sMVPInverted); // Inverted is normal due to OpenGL origin being bottom left if (!(flags & FLAG_INVERTED)) { mvp.scale(1.0f, -1.0f); } mvp.copyToMatrix4(sMVP); sCurrentModelViewProjection = sMVP; // cache current values sWidth = width; sHeight = height; sFlags = flags; }
void AssemblyReader::parseLinkedAssemblies(json_t *executableJSON) { json_t *ref_array = json_object_get(executableJSON, "references"); lmAssert(ref_array, "Error with executable assembly, missing references section"); for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString name = json_string_value(json_object_get(jref, "name")); json_t *jbinary = json_object_get(jref, "binary"); lmAssert(jbinary, "Error with linked assembly %s, missing binary section", name.c_str()); utString binary = (const char *)utBase64::decode64(json_string_value(jbinary)).getData().ptr(); linkedAssemblies.insert(utHashedString(name), binary); } }
static int _toNumber(lua_State *L) { lmAssert(lua_isstring(L, 1), "Non-string passed to String._toNumber"); const char *svalue = lua_tostring(L, 1); // if it is null or empty return -1 if (!svalue || !svalue[0]) { lua_pushnumber(L, -1); return 1; } float f; if (sscanf(svalue, "%f", &f) == 1) { lua_pushnumber(L, f); } else { lua_pushnumber(L, -1); } return 1; }
Expression *TypeCompiler::visit(NewExpression *expression) { FuncState *fs = cs->fs; Type *type = expression->function->type; lmAssert(type, "untyped new expression"); ExpDesc e; createInstance(&e, type->getFullName(), expression->arguments); if ((expression->function->astType == AST_VECTORLITERAL) || (expression->function->astType == AST_DICTIONARYLITERAL)) { // assign new instance expression->function->e = e; BC::expToNextReg(fs, &e); int restore = fs->freereg; // visit literal expression->function->visitExpression(this); fs->freereg = restore; } expression->e = e; return expression; }
void *loom_asset_imageDeserializer( void *buffer, size_t bufferLen, LoomAssetCleanupCallback *dtor ) { loom_asset_image_t *img; lmAssert(buffer != NULL, "buffer should not be null"); img = (loom_asset_image_t*)lmAlloc(gAssetAllocator, sizeof(loom_asset_image_t)); // parse any orientation info from exif format img->orientation = exifinfo_parse_orientation(buffer, (unsigned int)bufferLen); img->bits = stbi_load_from_memory((const stbi_uc *)buffer, (int)bufferLen, &img->width, &img->height, &img->bpp, 4); *dtor = loom_asset_imageDtor; if(!img->bits) { lmLogError(gImageAssetGroup, "Image load failed due to this cryptic reason: %s", stbi_failure_reason()); lmFree(gAssetAllocator, img); return 0; } lmLogDebug(gImageAssetGroup, "Allocated %d bytes for an image!", img->width * img->height * 4); return img; }
int loom_net_initialize() { // Platform-specific init. #if LOOM_PLATFORM == LOOM_PLATFORM_WIN32 WSADATA wsaData; WORD wVersionRequested = MAKEWORD(2, 0); int err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { lmLogError(netLogGroup, "Failed WinSock initalization with error %d", err); return 0; } if (((LOBYTE(wsaData.wVersion) != 2) || (HIBYTE(wsaData.wVersion) != 0)) && ((LOBYTE(wsaData.wVersion) != 1) || (HIBYTE(wsaData.wVersion) != 1))) { lmLogError(netLogGroup, "Failed WinSock initalization due to version mismatch"); WSACleanup(); return 0; } // Sanity checks. lmAssert(sizeof(SOCKET) <= sizeof(loom_socketId_t), "Can't pack a SOCKET into loom_socketId_t"); lmLogDebug(netLogGroup, "Initialized WinSock"); return 1; #else // Ignore sigpipe. lmLogDebug(netLogGroup, "Disabling signal SIGPIPE"); signal(SIGPIPE, SIG_IGN); return 1; #endif }
void loom_asset_initialize(const char *rootUri) { // Set up the lock for the mutex. lmAssert(gAssetLock == NULL, "Double initialization!"); gAssetLock = loom_mutex_create(); // Note the CWD. char tmpBuff[1024]; platform_getCurrentWorkingDir(tmpBuff, 1024); lmLog(gAssetLogGroup, "Current working directory ='%s'", tmpBuff); // And the allocator. //gAssetAllocator = loom_allocator_initializeTrackerProxyAllocator(loom_allocator_getGlobalHeap()); gAssetAllocator = (loom_allocator_getGlobalHeap()); // Clear, it might have been filled up before (for unit tests) gAssetLoadQueue.clear(); gAssetHash.clear(); // Asset server connection state. gAssetServerSocketLock = loom_mutex_create(); // And set up some default asset types. loom_asset_registerType(LATText, loom_asset_textDeserializer, loom_asset_textRecognizer); loom_asset_registerType(LATBinary, loom_asset_binaryDeserializer, loom_asset_binaryRecognizer); loom_asset_registerImageAsset(); loom_asset_registerSoundAsset(); loom_asset_registerScriptAsset(); // Listen to log and send it if we have a connection. loom_log_addListener(loom_asset_logListener, NULL); }
bool lualoom_pushnative(lua_State *L, NativeTypeBase *nativeType, void *p) { if (!p) { lua_pushnil(L); return false; } // whenever we are pushing an unmanaged class, we must wrap the instance in a new // userdata if (!nativeType->isManaged()) { // create the new userdata with given native type lualoom_newnativeuserdata(L, nativeType, p); // wrap the instance with the corresponding LoomScript class table lualoom_pushnative_userdata(L, NativeInterface::getScriptType(nativeType), -1); lua_remove(L, -2); // remove the user data } else { // we're managed NativeInterface::pushManagedNativeInternal(L, nativeType, p); lmAssert(lua_istable(L, -1), "Internal Error: unable to register managed native"); return true; } return false; }
void loom_asset_supply(const char *name, void *bits, int length) { loom_mutex_lock(gAssetLock); // Prep the asset. loom_asset_t *asset = loom_asset_getAssetByName(name, 1); // Make sure it's pristine. lmAssert(asset->state == loom_asset_t::Unloaded, "Can't supply an asset that's already queued or in process of loading. Supply assets before you make any asset requests!"); // Figure out the type from the path. utString nameAsUt = name; int type = loom_asset_recognizeAssetTypeFromPath(nameAsUt); if (type == 0) { lmLog(gAssetLogGroup, "Could not infer type of supplied resource '%s', skipping it...", name); asset->state = loom_asset_t::Unloaded; return; } // Deserialize it. LoomAssetCleanupCallback dtor = NULL; void *assetBits = loom_asset_deserializeAsset(name, type, length, bits, &dtor); // Instate the asset. // TODO: We can save some memory by pointing directly and not making a copy. asset->instate(type, assetBits, dtor); // Note it's supplied so we don't flush it. asset->isSupplied = 1; loom_mutex_unlock(gAssetLock); }
void loom_asset_registerType(unsigned int type, LoomAssetDeserializeCallback deserializer, LoomAssetRecognizerCallback recognizer) { lmAssert(gAssetDeserializerMap.find(type) == UT_NPOS, "Asset type already registered!"); gAssetDeserializerMap.insert(type, deserializer); gRecognizerList.push_back(recognizer); }
void BinWriter::writeMemberInfo(json_t *jminfo) { int iname = poolJString(json_object_get(jminfo, "name")); int isource = -1; int ilinenumber = -1; json_t *jsource = json_object_get(jminfo, "source"); if (jsource && json_is_string(jsource)) { isource = poolString(json_string_value(jsource)); ilinenumber = (int)json_integer_value(json_object_get(jminfo, "line")); } bytes.writeInt(iname); bytes.writeInt((int)json_integer_value(json_object_get(jminfo, "ordinal"))); bytes.writeInt(isource); bytes.writeInt(ilinenumber); json_t *meta_object = json_object_get(jminfo, "metainfo"); size_t meta_object_size = json_object_size(meta_object); // write the size of the object bytes.writeInt((int)meta_object_size); void *iter = json_object_iter(meta_object); size_t count = 0; while (iter) { // write the name to the pool table bytes.writeInt(poolString(json_object_iter_key(iter))); json_t *metaArray = json_object_iter_value(iter); // write the length of the meta array bytes.writeInt((int)json_array_size(metaArray)); for (UTsize i = 0; i < json_array_size(metaArray); i++) { json_t *keyArray = json_array_get(metaArray, i); // write the length of the key array bytes.writeInt((int)json_array_size(keyArray)); for (UTsize j = 0; j < json_array_size(keyArray); j++) { bytes.writeInt(poolString(json_string_value(json_array_get(keyArray, j)))); } } iter = json_object_iter_next(meta_object, iter); count++; } lmAssert(meta_object_size == count, "json object size mismatch"); }
VertexPosColorTex *QuadRenderer::getQuadVertices(TextureID texture, uint16_t numVertices, bool tinted, uint32_t srcBlend, uint32_t dstBlend) { if (!numVertices || (texture < 0) || (numVertices > MAXBATCHQUADS * 4)) { return NULL; } lmAssert(!(numVertices % 4), "numVertices % 4 != 0"); if (((currentTexture != TEXTUREINVALID) && (currentTexture != texture)) || (sTinted != tinted) || (srcBlend != sSrcBlend) || ( dstBlend != sDstBlend)) { submit(); } if ((vertexCount + numVertices) > MAXBATCHQUADS * 4) { submit(); if (numVertexBuffers == MAXVERTEXBUFFERS) { return NULL; } currentVertexBufferIdx++; if (currentVertexBufferIdx == numVertexBuffers) { // we need to allocate a new one _initializeNextVertexBuffer(); } currentIndexBufferIdx = 0; maxVertexIdx[currentVertexBufferIdx] = 0; currentVertexPtr = vertexData[currentVertexBufferIdx]; vertexCount = 0; quadCount = 0; } VertexPosColorTex *returnPtr = currentVertexPtr; sTinted = tinted; sSrcBlend = srcBlend; sDstBlend = dstBlend; currentVertexPtr += numVertices; vertexCount += numVertices; maxVertexIdx[currentVertexBufferIdx] = vertexCount; currentTexture = texture; quadCount += numVertices / 4; return returnPtr; }
void BinWriter::writeExecutable(const char *path, const char *sjson, int jsonSize) { json_error_t jerror; json_t *json = json_loadb(sjson, jsonSize, 0, &jerror); lmAssert(json, "Error loading Assembly json: %s\n %s %i\n", jerror.source, jerror.text, jerror.line); writeExecutable(path, json); }