public static bool Insert(Data.ChunkData data) { if (data == null || data.DataBaseID > -1) { return(false); } SqlConnection conn = GameApplication.Current.ConnectionManager.OpenConnection(); try { SqlCommand comm = new SqlCommand(@"INSERT INTO dbo.Chunk(MapID,X,Y,Z) OUTPUT INSERTED.ID VALUES(@MapID, @X,@Y,@Z)", conn); comm.Parameters.AddWithValue("MapID", data.MapID); comm.Parameters.AddWithValue("Y", data.Position.y); comm.Parameters.AddWithValue("X", data.Position.x); comm.Parameters.AddWithValue("Z", data.Position.z); long ID = (long)comm.ExecuteScalar(); lock (data) { data.DataBaseID = ID; } return(true); } catch (Exception) { return(false); } finally { GameApplication.Current.ConnectionManager.CloseConnection(conn); } }
private bool DequeueChunk(out string error) { error = null; try { Data.ChunkData chunk = null; lock (ChunkInsertQueue) { try { chunk = ChunkInsertQueue.Dequeue(); } //empty queue catch (InvalidOperationException) { } } if (chunk != null) { lock (chunk) { if (!DAO.Terrain.ChunkData.Insert(chunk) && chunk.DataBaseID <= -1) { lock (ChunkInsertQueue) { //try again later ChunkInsertQueue.Enqueue(chunk); } } else { //atualiza index de base de dados adicionando o novo id var dataBaseHashKey = chunk.DataBaseID.GetHashCode(); var dataBaseChunks = this.ChunksByDataBaseID.GetOrAdd(dataBaseHashKey, new List <Data.ChunkData>()); lock (dataBaseChunks) { dataBaseChunks.Add(chunk); } } } } return(true); } catch (Exception ex) { error = ex.ToString(); return(false); } }
private static bool LoadAllChunksWithNoBlocks(out string error) { error = null; SqlConnection conn = GameApplication.Current.ConnectionManager.OpenConnection(); try { SqlCommand comm = new SqlCommand("select * from dbo.Chunk", conn); comm.CommandTimeout = 10000; using (var reader = comm.ExecuteReader()) { //Nenhum Chunk while (reader.Read()) { long ID = (long)reader["ID"]; int x = (int)reader["X"]; int y = (int)reader["Y"]; int z = (int)reader["Z"]; int MapID = (int)reader["MapID"]; Data.ChunkData chunkData = new Data.ChunkData(MapID, ID, new SandBoxEngine.Terrain.Utils.Vector3i(x, y, z)); long MemoryID = GameApplication.Current.Terrain.AddChunk(chunkData); if (MemoryID == -1) { error = string.Format("Failed to add chunk to memory [DataBaseID: {0}]", ID); return(false); } } return(true); } } catch (Exception ex) { error = ex.ToString(); return(false); } finally { GameApplication.Current.ConnectionManager.CloseConnection(conn); } }
public static Data.ChunkData Load(long DataBaseID, out string error) { error = null; SqlConnection conn = GameApplication.Current.ConnectionManager.OpenConnection(); try { if (DataBaseID <= -1) { error = string.Format("Invalid chunk database id [DataBaseID: {0}]", DataBaseID); return(null); } StringBuilder query = new StringBuilder(); query.AppendLine("select * from dbo.Chunk where ID = @chunkID"); query.AppendLine(@"select * from dbo.BlockData where ChunkID = @chunkID"); SqlCommand comm = new SqlCommand(query.ToString(), conn); comm.Parameters.AddWithValue("chunkID", DataBaseID); using (var reader = comm.ExecuteReader()) { if (!reader.Read()) { error = string.Format("Invalid chunk not found [DataBaseID: {0}]", DataBaseID); return(null); } int x = (int)reader["X"]; int y = (int)reader["Y"]; int z = (int)reader["Z"]; int MapID = (int)reader["MapID"]; Data.ChunkData chunkData = new Data.ChunkData(MapID, DataBaseID, new SandBoxEngine.Terrain.Utils.Vector3i(x, y, z)); long MemoryID = GameApplication.Current.Terrain.AddChunk(chunkData); lock (chunkData) { if (MemoryID == -1) { error = string.Format("Failed to add chunk to memory [DataBaseID: {0}]", DataBaseID); return(null); } if (reader.NextResult()) { while (reader.Read()) { long ID = (long)reader["ID"]; long ChunkID = (long)reader["ChunkiD"]; byte X = (byte)reader["X"]; byte Y = (byte)reader["Y"]; byte Z = (byte)reader["Z"]; int BlockID = (int)reader["BlockID"]; float isovalue = Convert.ToSingle(reader["IsoValue"]); bool IsDestroyed = (bool)reader["IsDestroyed"]; bool IsPathBlocked = (bool)reader["IsPathBlocked"]; var blockData = new Data.BlockData(MemoryID, ID, GameApplication.Current.Terrain.BlockSet.Blocks[BlockID], new SandBoxEngine.Terrain.Utils.Vector3i(X, Y, Z), isovalue, IsPathBlocked, IsDestroyed); chunkData.Blocks[X][Y][Z] = blockData; } } } return(chunkData); } } catch (Exception ex) { error = ex.ToString(); return(null); } finally { GameApplication.Current.ConnectionManager.CloseConnection(conn); } }
private bool DequeueBlock(out string error) { error = null; try { Data.BlockData block = null; lock (BlockInsertOrUpdateQueue) { try { block = BlockInsertOrUpdateQueue.Dequeue(); } //empty queue catch (InvalidOperationException) { } } if (block != null) { lock (block) { bool enqueueAgain; Data.ChunkData chunk = ChunkByMemoryID(block.ChunkMemoryID); bool chunkSaved; lock (chunk) { chunkSaved = chunk.DataBaseID > -1; } //verifica se o chunk foi salvo no banco if (chunkSaved) { if (block.DataBaseID <= -1) { enqueueAgain = (!DAO.Terrain.BlockData.Insert(block) && block.DataBaseID <= -1); } else { enqueueAgain = (!DAO.Terrain.BlockData.Update(block)); } } else// aguarda na fila ate que seu chunk esteja salvo no banco de dados { enqueueAgain = true; } if (enqueueAgain) { lock (BlockInsertOrUpdateQueue) { //try again later BlockInsertOrUpdateQueue.Enqueue(block); } } } } return(true); } catch (Exception ex) { error = ex.ToString(); return(false); } }
/// <summary> /// Adiciona novo chunk no cache de memoria /// </summary> /// <param name="chunk">Chunk a ser adiciona no cache de memoria</param> /// <returns>Retorna ID na memoria gerado para o chunk ou -1 caso não consiga adicionar o id de memoria do chunk é atualizado no objeto caso tenha sucesso</returns> public long AddChunk(Data.ChunkData chunk) { if (chunk == null) { return(-1); } int maxX = MapLimits.x; int maxZ = MapLimits.z; int maxY = MapLimits.y; if (MapLimits.x < chunk.Position.x) { maxX = chunk.Position.x; } if (MapLimits.y < chunk.Position.y) { maxY = chunk.Position.y; } if (MapLimits.z < chunk.Position.z) { maxZ = chunk.Position.z; } MapLimits = new Vector3i(maxX, maxY, maxZ); int positionHashKey = chunk.Position.GetHashCode(); //busca ou cria index para o hash var positionIndexedChunks = this.PositionIndexedChunks.GetOrAdd(positionHashKey, new List <Data.ChunkData>()); long MemoryID = -1; //incrementa ID lock (LockChunkMemoryIDIncrement) { LastChunkMemoryID++; MemoryID = LastChunkMemoryID; } var hashKey = MemoryID.GetHashCode(); //Tenta adicionar na memoria e no hashIndex var chunks = this.ChunksByMemoryID.GetOrAdd(hashKey, new List <Data.ChunkData>()); lock (chunks) { chunks.Add(chunk); } chunk.MemoryID = MemoryID; lock (positionIndexedChunks) { //adiciona no index positionIndexedChunks.Add(chunk); } if (chunk.DataBaseID <= -1) { lock (ChunkInsertQueue) { ChunkInsertQueue.Enqueue(chunk); } } else { //adiciona no index de base de dados caso ja exista o ID do banco var dataBaseHashKey = chunk.DataBaseID.GetHashCode(); var dataBaseChunks = this.ChunksByDataBaseID.GetOrAdd(dataBaseHashKey, new List <Data.ChunkData>()); lock (dataBaseChunks) { dataBaseChunks.Add(chunk); } } return(MemoryID); }