long long ServerRepo::GetUserId(const String& userName) { BEGIN_TRY(); // try to find user id { Data::SqliteQuery query(stmtGetUserId); stmtGetUserId->Bind(1, userName); switch(stmtGetUserId->Step()) { case SQLITE_ROW: return stmtGetUserId->ColumnInt64(0); case SQLITE_DONE: // no such user break; default: THROW_SECONDARY("Can't find user id", db->Error()); } } // add new user { Data::SqliteQuery query(stmtAddUser); stmtAddUser->Bind(1, userName); if(stmtAddUser->Step() != SQLITE_DONE) THROW("Can't add new user"); return db->LastInsertRowId(); } END_TRY("Can't get user id"); }
ptr<RigidBody> BtWorld::CreateRigidBody(ptr<Shape> abstractShape, float mass, const mat4x4& startTransform) { try { ptr<BtShape> shape = abstractShape.FastCast<BtShape>(); if(!shape) THROW("Non-bullet shape"); btCollisionShape* collisionShape = shape->GetInternalObject(); btVector3 localInertia(0, 0, 0); if(mass != 0) collisionShape->calculateLocalInertia(mass, localInertia); ptr<BtRigidBody> rigidBody = NEW(BtRigidBody(this, shape, toBt(startTransform))); btRigidBody::btRigidBodyConstructionInfo info(mass, &*rigidBody, shape->GetInternalObject(), localInertia); btRigidBody* internalRigidBody = new btRigidBody(info); rigidBody->SetInternalObject(internalRigidBody); dynamicsWorld->addRigidBody(internalRigidBody); return rigidBody; } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet rigid body", exception); } }
BEGIN_INANITY_SHADERS GlslGeneratorInstance::GlslGeneratorInstance(ptr<Node> rootNode, ShaderType shaderType, GlslVersion glslVersion, bool supportUniformBuffers) : SlGeneratorInstance(rootNode, shaderType), glslVersion(glslVersion), supportUniformBuffers(supportUniformBuffers) { try { switch(shaderType) { case ShaderTypes::vertex: uniformPrefix = "uv"; uniformBufferPrefix = "UBv"; samplerPrefix = "sv"; break; case ShaderTypes::pixel: uniformPrefix = "up"; uniformBufferPrefix = "UBp"; samplerPrefix = "sp"; break; default: THROW("Wrong shader type"); } } catch(Exception* exception) { THROW_SECONDARY("Can't create GLSL generator instance", exception); } }
ptr<Character> BtWorld::CreateCharacter(ptr<Shape> abstractShape, const mat4x4& startTransform) { try { ptr<BtShape> shape = abstractShape.FastCast<BtShape>(); if(!shape) THROW("Non-bullet shape"); btConvexShape* collisionShape = fast_cast<btConvexShape*>(shape->GetInternalObject()); btPairCachingGhostObject* ghost = new btPairCachingGhostObject(); ghost->setWorldTransform(toBt(startTransform)); ghost->setCollisionShape(collisionShape); ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); // 2 - номер оси "вверх" - Z btKinematicCharacterController* controller = new btKinematicCharacterController(ghost, collisionShape, 0.5f, 2); dynamicsWorld->addCollisionObject(ghost); //dynamicsWorld->addCollisionObject(ghost, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter); dynamicsWorld->addAction(controller); return NEW(BtCharacter(this, shape, ghost, controller)); } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet character", exception); } }
ptr<Platform::Window> SdlAdapter::CreateOptimizedWindow(const String& title, int left, int top, int width, int height) { SDL_Window* handle = SDL_CreateWindow(title.c_str(), left, top, width, height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI); if(!handle) THROW_SECONDARY("Can't create SDL-optimized window", Platform::Sdl::Error()); return NEW(Platform::SdlWindow(handle)); }
long long ServerRepo::GetMaxRevision() { Data::SqliteQuery query(stmtGetMaxRevision); if(stmtGetMaxRevision->Step() != SQLITE_ROW) THROW_SECONDARY("Can't get max revision", db->Error()); return stmtGetMaxRevision->ColumnInt64(0); }
void CriticalSection::Leave() { #if defined(___INANITY_PLATFORM_WINDOWS) LeaveCriticalSection(&criticalSection); #elif defined(___INANITY_PLATFORM_POSIX) if(pthread_mutex_unlock(&mutex)) THROW_SECONDARY("Can't leave critical section", Exception::SystemError()); #else #error Unknown platform #endif }
BEGIN_INANITY CriticalSection::CriticalSection() { try { #if defined(___INANITY_PLATFORM_WINDOWS) InitializeCriticalSection(&criticalSection); #elif defined(___INANITY_PLATFORM_POSIX) if(pthread_mutex_init(&mutex, 0)) THROW_SECONDARY("Can't initialize mutex", Exception::SystemError()); #else #error Unknown platform #endif } catch(Exception* exception) { THROW_SECONDARY("Can't create critical section", exception); } }
ptr<InputStream> FileSystem::LoadStream(const String& fileName) { try { return NEW(FileInputStream(LoadFile(fileName))); } catch(Exception* exception) { THROW_SECONDARY("Can't load file " + fileName + " as stream", exception); } }
void Thread::WaitEnd() { #if defined(___INANITY_PLATFORM_WINDOWS) if(WaitForSingleObject(*thread, INFINITE) != WAIT_OBJECT_0) #elif defined(___INANITY_PLATFORM_POSIX) if(pthread_join(thread, 0)) #else #error Unknown platform #endif THROW_SECONDARY("Can't wait for thread end", Exception::SystemError()); }
ptr<OutputStream> BufferedFileSystem::SaveStream(const String& fileName) { try { return NEW(BufferedOutputStream(fileSystem->SaveStream(fileName))); } catch(Exception* exception) { THROW_SECONDARY("Can't save stream in buffered file system", exception); } }
ptr<InputStream> BufferedFileSystem::LoadStream(const String& fileName) { try { return NEW(BufferedInputStream(fileSystem->LoadStream(fileName))); } catch(Exception* exception) { THROW_SECONDARY("Can't load stream from buffered file system", exception); } }
BlobFileSystem::BlobFileSystem(ptr<File> file) : file(file) { try { void* fileData = file->GetData(); size_t fileSize = file->GetSize(); size_t size = fileSize; //получить терминатор if(size < sizeof(Terminator)) THROW("Can't read terminator"); Terminator* terminator = (Terminator*)((char*)fileData + fileSize) - 1; size -= sizeof(*terminator); //проверить сигнатуру if(memcmp(terminator->magic, Terminator::magicValue, sizeof(terminator->magic)) != 0) THROW("Invalid magic"); //проверить, что заголовок читается if(size < terminator->headerSize) THROW("Can't read header"); //получить читатель заголовка ptr<StreamReader> headerReader = NEW(StreamReader(NEW(FileInputStream( NEW(PartFile(file, (char*)terminator - terminator->headerSize, terminator->headerSize)))))); size -= terminator->headerSize; //считывать файлы, пока есть for(;;) { //считать имя файла String fileName = headerReader->ReadString(); //если оно пустое, значит, это конец if(fileName.empty()) break; //считать смещение до файла и его размер size_t fileOffset = headerReader->ReadShortly(); size_t fileSize = headerReader->ReadShortly(); //проверить, что файл читается if(fileOffset > size || size - fileOffset < fileSize) THROW("Can't read file " + fileName); //добавить файл в карту files[fileName] = NEW(PartFile(file, (char*)fileData + fileOffset, fileSize)); } } catch(Exception* exception) { THROW_SECONDARY("Can't load blob file system", exception); } }
/* Между вызовами Write и между итерациями цикла внутри Write поддерживается следующий инвариант. Входной буфер - может содержать данные next_in - начало входного буфера avail_in - размер этих данных Выходной буфер - всегда пустой next_out - начало выходного буфера avail_out - размер выходного буфера */ void DeflateStream::Write(const void* data, size_t size) { try { //если финализация уже была выполнена, то записывать данные нельзя if(finalized) THROW("Stream already finalized"); //запомнить параметры буферов Bytef* inputBuffer = zstream.next_in; Bytef* outputBuffer = zstream.next_out; unsigned outputSize = zstream.avail_out; //пока есть данные while(size) { //приписать данные к концу входного буфера unsigned toRead = (unsigned)std::min<size_t>(size, inputBufferSize - zstream.avail_in); memcpy(zstream.next_in + zstream.avail_in, data, toRead); zstream.avail_in += toRead; data = (char*)data + toRead; size -= toRead; //если входной буфер переполнен if(zstream.avail_in >= inputBufferSize) { //выполнить сжатие данных switch(deflate(&zstream, Z_NO_FLUSH)) { case Z_OK: case Z_BUF_ERROR: break; default: THROW("Compression error"); } //записать данные в выходной поток WriteOutput(outputBuffer, outputSize - zstream.avail_out); //перенести данные, которые остались во входном буфере, в его начало memmove(inputBuffer, zstream.next_in, zstream.avail_in); zstream.next_in = inputBuffer; //очистить выходной буфер zstream.next_out = outputBuffer; zstream.avail_out = outputSize; } } } catch(Exception* exception) { THROW_SECONDARY("Can't compress data", exception); } }
ptr<Shape> BtWorld::CreateBoxShape(const vec3& halfSize) { try { btCollisionShape* collisionShape = new btBoxShape(toBt(halfSize)); return NEW(BtShape(this, collisionShape)); } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet box shape", exception); } }
ptr<Shape> BtWorld::CreateCapsuleShape(float radius, float height) { try { btCollisionShape* collisionShape = new btCapsuleShape(radius, height); return NEW(BtShape(this, collisionShape)); } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet box shape", exception); } }
/* Во время и после Flush указанный для Write инвариант не выполняется. */ void DeflateStream::Flush() { try { //если финализация уже была выполнена, закончить if(finalized) return; //запомнить параметры выходного буфера Bytef* outputBuffer = zstream.next_out; unsigned outputSize = zstream.avail_out; //цикл, пока компрессия не завершена for(;;) { //выполнять компрессию int result = deflate(&zstream, Z_FINISH); //обработка ошибок switch(result) { case Z_STREAM_END: case Z_OK: break; default: THROW("Compression error"); } //записать вывод в поток WriteOutput(outputBuffer, outputSize - zstream.avail_out); //очистить выходной буфер zstream.next_out = outputBuffer; zstream.avail_out = outputSize; //если это конец, закончить if(result == Z_STREAM_END) break; } //завершить сжатие if(deflateEnd(&zstream) != Z_OK) THROW("Finalize stream error"); //установить флажок завершенности finalized = true; } catch(Exception* exception) { THROW_SECONDARY("Can't finalize compression", exception); } }
BEGIN_INANITY Thread::Thread(ptr<ThreadHandler> handler) : handler(handler) { try { #if defined(___INANITY_PLATFORM_WINDOWS) thread = NEW(Platform::Win32Handle(CreateThread(0, 0, ThreadRoutine, this, 0, 0))); if(!thread->IsValid()) THROW_SECONDARY("CreateThread failed", Exception::SystemError()); #elif defined(___INANITY_PLATFORM_POSIX) if(pthread_create(&thread, 0, ThreadRoutine, this)) THROW_SECONDARY("pthread_create failed", Exception::SystemError()); #else #error Unknown platform #endif Reference(); } catch(Exception* exception) { THROW_SECONDARY("Can't create thread", exception); } }
ptr<Win32Window> Win32Window::CreateForOpenGL(const String& title, int left, int top, int width, int height, bool visible) { BEGIN_TRY(); static ATOM windowClass = NULL; //зарегистрировать класс окна, если еще не сделано if(!windowClass) { WNDCLASS wndClass; ZeroMemory(&wndClass, sizeof(wndClass)); wndClass.style = CS_OWNDC; wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.lpszClassName = TEXT("Win32OpenGLWindow"); wndClass.hInstance = GetModuleHandle(NULL); wndClass.lpfnWndProc = StaticWndProc; windowClass = RegisterClass(&wndClass); if(!windowClass) THROW("Can't register window class"); } ptr<Win32Window> window = Create(windowClass, title, left, top, width, height, visible); // get window's persistent HDC HDC hdc = GetDC(window->GetHWND()); if(!hdc) THROW_SECONDARY("Can't get window's HDC", Exception::SystemError()); // store it to window window->hdc = hdc; // choose & set pixel format PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 0; pfd.iLayerType = PFD_MAIN_PLANE; int pixelFormat = ChoosePixelFormat(hdc, &pfd); if(!pixelFormat) THROW("Can't choose pixel format"); if(!SetPixelFormat(hdc, pixelFormat, &pfd)) THROW("Can't set pixel format"); return window; END_TRY("Can't create window for OpenGL"); }
BEGIN_INANITY_GRAPHICS SdlAdapter::SdlAdapter(int videoDriverIndex) : sdl(Platform::Sdl::Get(SDL_INIT_VIDEO)), monitorsInitialized(false) { BEGIN_TRY(); const char* videoDriverName = SDL_GetVideoDriver(videoDriverIndex); if(!videoDriverName) THROW_SECONDARY("Can't get video driver name", Platform::Sdl::Error()); name = videoDriverName; END_TRY("Can't create SDL adapter"); }
BEGIN_INANITY_GRAPHICS DxgiMonitor::DxgiMonitor(ComPointer<IDXGIOutput> output) : output(output), modesInitialized(false) { try { if(FAILED(output->GetDesc(&desc))) THROW("Can't get desc"); } catch(Exception* exception) { THROW_SECONDARY("Can't create DXGI monitor", exception); } }
RECT DxgiMonitor::GetRect() const { try { MONITORINFO info; info.cbSize = sizeof(info); if(!GetMonitorInfo(desc.Monitor, &info)) THROW("Can't get monitor info"); return info.rcMonitor; } catch(Exception* exception) { THROW_SECONDARY("Can't get DXGI monitor rect", exception); } }
ptr<Platform::Window> DxgiMonitor::CreateDefaultWindow(const String& title, int width, int height) { try { RECT rect = GetRect(); return Platform::Win32Window::CreateForDirectX( title, rect.left + (rect.right - rect.left - width) / 2, rect.top + (rect.bottom - rect.top - height) / 2, width, height ); } catch(Exception* exception) { THROW_SECONDARY("Can't create window centered in DXGI monitor", exception); } }
void StreamHasher::VerifyStream::ReadBlock() { try { // считать исходные данные blockDataSize = sourceDataStream->Read(block, blockSize); blockReadSize = 0; // считать оригинальный хеш (тот, который должен быть) void* originalHash = alloca(hashSize); size_t originalHashSize = sourceHashStream->Read(originalHash, hashSize); // если исходные данные есть, то и хеш должен быть // а если исходных данных нет, то и хеша не должно if(blockDataSize) { if(originalHashSize != hashSize) THROW("Can't read hash"); } else { if(originalHashSize) THROW("Extra hash after data end"); // данных нет, и больше делать нечего return; } // получить хеш исходных данных hashStream->Reset(); hashStream->Write(block, blockDataSize); hashStream->End(); void* dataHash = alloca(hashSize); hashStream->GetHash(dataHash); // сравнить его с оригинальным if(memcmp(originalHash, dataHash, hashSize) != 0) THROW("Wrong data hash"); // всё хорошо, данные можно использовать } catch(Exception* exception) { THROW_SECONDARY("Can't read block in verify stream of stream hasher", exception); } }
const Adapter::Monitors& SdlAdapter::GetMonitors() { BEGIN_TRY(); if(!monitorsInitialized) { int monitorsCount = SDL_GetNumVideoDisplays(); if(monitorsCount <= 0) THROW_SECONDARY("Can't get number of video displays", Platform::Sdl::Error()); monitors.resize(monitorsCount); for(int i = 0; i < monitorsCount; ++i) monitors[i] = NEW(SdlMonitor(i)); monitorsInitialized = true; } return monitors; END_TRY("Can't get SDL monitors"); }
ptr<File> DeflateStream::CompressFile(ptr<File> file, CompressionLevel compressionLevel) { try { //создать выходной поток ptr<MemoryStream> outputStream = NEW(MemoryStream); //создать поток для сжатия ptr<DeflateStream> stream = NEW(DeflateStream(&*outputStream, compressionLevel)); //сжать данные stream->Write(file->GetData(), file->GetSize()); stream->Flush(); //вернуть файл return outputStream->ToFile(); } catch(Exception* exception) { THROW_SECONDARY("Can't decompress to file", exception); } }
RECT Win32Monitor::GetRect() const { try { // code below is not working for some reason // EnumDisplaySettingsEx always return false #if 0 DEVMODE modeInfo; modeInfo.dmSize = sizeof(modeInfo); modeInfo.dmDriverExtra = 0; std::cout << deviceName << "\n"; if(!EnumDisplaySettingsEx(info.DeviceName, ENUM_CURRENT_SETTINGS, &modeInfo, 0)) THROW("Can't get current mode"); RECT rect; rect.left = (modeInfo.dmFields & DM_POSITION) ? modeInfo.dmPosition.x : 0; rect.top = (modeInfo.dmFields & DM_POSITION) ? modeInfo.dmPosition.y : 0; rect.right = rect.left + ((modeInfo.dmFields & DM_PELSWIDTH) ? modeInfo.dmPelsWidth : 0); rect.bottom = rect.top + ((modeInfo.dmFields & DM_PELSHEIGHT) ? modeInfo.dmPelsHeight : 0); return rect; #else // temporary "fix" RECT rect; rect.left = 0; rect.top = 0; rect.right = GetSystemMetrics(SM_CXSCREEN); rect.bottom = GetSystemMetrics(SM_CYSCREEN); return rect; #endif } catch(Exception* exception) { THROW_SECONDARY("Can't get Win32 monitor rect", exception); } }
ptr<MonitorMode> DxgiMonitor::TryCreateMode(int width, int height) { try { DXGI_MODE_DESC desc; desc.Width = width; desc.Height = height; desc.RefreshRate.Numerator = 0; desc.RefreshRate.Denominator = 0; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; DXGI_MODE_DESC closestDesc; if(FAILED(output->FindClosestMatchingMode(&desc, &closestDesc, nullptr))) return 0; return NEW(DxgiMonitorMode(closestDesc)); } catch(Exception* exception) { THROW_SECONDARY("Can't create DXGI mode", exception); } }
const Monitor::MonitorModes& DxgiMonitor::GetModes() { if(!modesInitialized) try { UINT modesCount; if(FAILED(output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &modesCount, NULL))) THROW("Can't get modes count"); std::vector<DXGI_MODE_DESC> modeDescs(modesCount); if(FAILED(output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &modesCount, &*modeDescs.begin()))) THROW("Can't get modes"); for(UINT i = 0; i < modesCount; ++i) modes.push_back(NEW(DxgiMonitorMode(modeDescs[i]))); modesInitialized = true; } catch(Exception* exception) { THROW_SECONDARY("Can't get modes of DXGI monitor", exception); } return modes; }
BEGIN_INANITY_PHYSICS BtWorld::BtWorld() : collisionConfiguration(0), collisionDispatcher(0), broadphase(0), solver(0), dynamicsWorld(0) { try { collisionConfiguration = new btDefaultCollisionConfiguration(); collisionDispatcher = new btCollisionDispatcher(collisionConfiguration); broadphase = new btDbvtBroadphase(); solver = new btSequentialImpulseConstraintSolver(); dynamicsWorld = new btDiscreteDynamicsWorld(collisionDispatcher, broadphase, solver, collisionConfiguration); broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback()); dynamicsWorld->setGravity(btVector3(0, 0, -9.8)); } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet world", exception); } }