Spin off terrain save into a new thread and make it so that it uses the old

values for places where NaN are found.
avinationmerge
Melanie 2011-12-13 12:58:28 +01:00
parent 6d1d1c0dbf
commit df65245671
1 changed files with 35 additions and 30 deletions

View File

@ -561,45 +561,46 @@ namespace OpenSim.Data.MySQL
public virtual void StoreTerrain(double[,] ter, UUID regionID) public virtual void StoreTerrain(double[,] ter, UUID regionID)
{ {
m_log.Info("[REGION DB]: Storing terrain"); Util.FireAndForget(delegate(object x)
lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) double[,] oldTerrain = LoadTerrain(regionID);
m_log.Info("[REGION DB]: Storing terrain");
lock (m_dbLock)
{ {
dbcon.Open(); using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
using (MySqlCommand cmd = dbcon.CreateCommand())
{ {
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; dbcon.Open();
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
using (MySqlCommand cmd2 = dbcon.CreateCommand()) using (MySqlCommand cmd = dbcon.CreateCommand())
{ {
try cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
{ cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
cmd2.CommandText = "insert into terrain (RegionUUID, " +
"Revision, Heightfield) values (?RegionUUID, " +
"1, ?Heightfield)";
cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); using (MySqlCommand cmd2 = dbcon.CreateCommand())
cmd2.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter));
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd2);
}
catch
{ {
// If we get here there is a NaN in the terrain try
// and the terrain can't be saved. A crash here {
// is much better than losing all the work cmd2.CommandText = "insert into terrain (RegionUUID, " +
m_log.ErrorFormat("[DATA]: Unable to save terrain. Stopping simulator to prevent data loss"); "Revision, Heightfield) values (?RegionUUID, " +
Environment.Exit(1); "1, ?Heightfield)";
cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
cmd2.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter, oldTerrain));
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd2);
}
catch (Exception e)
{
m_log.ErrorFormat(e.ToString());
}
} }
} }
} }
} }
} });
} }
public virtual double[,] LoadTerrain(UUID regionID) public virtual double[,] LoadTerrain(UUID regionID)
@ -1411,7 +1412,7 @@ namespace OpenSim.Data.MySQL
/// </summary> /// </summary>
/// <param name="val"></param> /// <param name="val"></param>
/// <returns></returns> /// <returns></returns>
private static Array SerializeTerrain(double[,] val) private static Array SerializeTerrain(double[,] val, double[,] oldTerrain)
{ {
MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double)); MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
BinaryWriter bw = new BinaryWriter(str); BinaryWriter bw = new BinaryWriter(str);
@ -1420,7 +1421,11 @@ namespace OpenSim.Data.MySQL
for (int x = 0; x < (int)Constants.RegionSize; x++) for (int x = 0; x < (int)Constants.RegionSize; x++)
for (int y = 0; y < (int)Constants.RegionSize; y++) for (int y = 0; y < (int)Constants.RegionSize; y++)
{ {
double height = val[x, y]; double height = 20.0;
if (oldTerrain != null)
height = oldTerrain[x, y];
if (!double.IsNaN(val[x, y]))
height = val[x, y];
if (height == 0.0) if (height == 0.0)
height = double.Epsilon; height = double.Epsilon;