Added, Tag Explorer plugin, UDMF: added multiple tags support.

Changed, cosmetic: elapsed time is now displayed after resources loading finishes.
Changed, internal: changed Clock.CurrentTime type to long.
Fixed, Tag Statistics window: in some cases the map view was not updated after selecting items in Sectors/Linedefs/Things columns.
Fixed, cosmetic: Draw Curve mode icon was missing a shadow.
This commit is contained in:
MaxED 2016-03-14 00:01:21 +00:00 committed by spherallic
parent 1dbc431aeb
commit f37fc2c662
18 changed files with 127 additions and 168 deletions

View file

@ -100,7 +100,7 @@ namespace CodeImp.DoomBuilder.Compilers
if(!isdisposed)
{
Exception deleteerror;
float starttime = Clock.CurrentTime;
long starttime = Clock.CurrentTime;
do
{

View file

@ -22,6 +22,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
@ -119,8 +120,8 @@ namespace CodeImp.DoomBuilder.Data
private Dictionary<int, ThingTypeInfo> thingtypes;
// Timing
private float loadstarttime;
private float loadfinishtime;
private long loadstarttime;
private long loadfinishtime;
// Disposing
private bool isdisposed;
@ -728,12 +729,6 @@ namespace CodeImp.DoomBuilder.Data
}
else
{
if(notifiedbusy)
{
notifiedbusy = false;
General.SendMessage(General.MainWindow.Handle, (int)MainForm.ThreadMessages.UpdateStatus, 0, 0);
}
// Timing
if(loadfinishtime == 0)
{
@ -744,8 +739,21 @@ namespace CodeImp.DoomBuilder.Data
}
loadfinishtime = Clock.CurrentTime;
float deltatimesec = (loadfinishtime - loadstarttime) / 1000.0f;
General.WriteLogLine("Resources loading took " + deltatimesec.ToString("########0.00") + " seconds");
string deltatimesec = ((loadfinishtime - loadstarttime) / 1000.0f).ToString("########0.00");
General.WriteLogLine("Resources loading took " + deltatimesec + " seconds");
//mxd. Show more detailed message
if(notifiedbusy)
{
notifiedbusy = false;
IntPtr strptr = Marshal.StringToCoTaskMemAuto(deltatimesec);
General.SendMessage(General.MainWindow.Handle, (int)MainForm.ThreadMessages.ResourcesLoaded, strptr.ToInt32(), 0);
}
}
else if(notifiedbusy) //mxd. Sould never happen (?)
{
notifiedbusy = false;
General.SendMessage(General.MainWindow.Handle, (int)MainForm.ThreadMessages.UpdateStatus, 0, 0);
}
// Wait longer to release CPU resources

View file

@ -461,7 +461,8 @@ namespace CodeImp.DoomBuilder.Editing
#region ================== Processing
// Processing
public override void OnProcess(float deltatime)
public override void OnProcess(float deltatime) { OnProcess((long)deltatime); } //mxd. DB2 compatibility
public override void OnProcess(long deltatime)
{
base.OnProcess(deltatime);

View file

@ -245,7 +245,8 @@ namespace CodeImp.DoomBuilder.Editing
public virtual void OnPresentDisplay() { }
// Processing events
public virtual void OnProcess(float deltatime) { }
public virtual void OnProcess(long deltatime) { }
public virtual void OnProcess(float deltatime) { OnProcess((long)deltatime); } //mxd. DB2 compatibility
// Generic events
public virtual void OnReloadResources() { }

View file

@ -84,7 +84,6 @@
this.dataGridView.Size = new System.Drawing.Size(477, 256);
this.dataGridView.TabIndex = 3;
this.dataGridView.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView_CellMouseClick);
this.dataGridView.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView_CellMouseDoubleClick);
//
// TagColumn
//

View file

@ -168,7 +168,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
return list;
}
private static void ShowSelection(List<Vector2D> points)
private static void ShowSelection(IEnumerable<Vector2D> points)
{
RectangleF area = MapSet.CreateEmptyArea();
@ -235,13 +235,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
int tag = (int)dataGridView.Rows[e.RowIndex].Cells[0].Value;
if(e.ColumnIndex == 2) //sectors
{
{
// Deselect everything
General.Map.Map.ClearAllSelected();
List<Sector> list = GetSectorsWithTag(tag, (int)dataGridView.Rows[e.RowIndex].Cells[2].Value);
if(list.Count > 0)
{
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedLinedefs();
List<Vector2D> points = new List<Vector2D>();
General.Editing.ChangeMode("SectorsMode");
ClassicMode mode = (ClassicMode)General.Editing.Mode;
@ -259,15 +259,20 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
ShowSelection(points);
}
else
{
General.Interface.RedrawDisplay();
}
}
else if(e.ColumnIndex == 3) //linedefs
{
{
// Deselect everything
General.Map.Map.ClearAllSelected();
List<Linedef> list = GetLinedefsWithTag(tag, (int)dataGridView.Rows[e.RowIndex].Cells[3].Value);
if(list.Count > 0)
{
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedLinedefs();
General.Editing.ChangeMode("LinedefsMode");
List<Vector2D> points = new List<Vector2D>();
foreach(Linedef l in list)
{
@ -277,19 +282,24 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
}
General.Map.Map.Update();
General.Editing.ChangeMode("LinedefsMode");
ShowSelection(points);
}
else
{
General.Interface.RedrawDisplay();
}
}
else if(e.ColumnIndex == 4) //things
{
{
// Deselect everything
General.Map.Map.ClearAllSelected();
List<Thing> list = GetThingsWithTag(tag, (int)dataGridView.Rows[e.RowIndex].Cells[4].Value);
if(list.Count > 0)
if(list.Count > 0)
{
General.Map.Map.ClearSelectedThings();
General.Editing.ChangeMode("ThingsMode");
List<Vector2D> points = new List<Vector2D>();
foreach(Thing t in list)
foreach(Thing t in list)
{
t.Selected = true;
@ -302,12 +312,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
}
General.Map.Map.Update();
General.Editing.ChangeMode("ThingsMode");
ShowSelection(points);
}
else
{
General.Interface.RedrawDisplay();
}
}
}
else if(e.Button == MouseButtons.Right) //open properties window
{
@ -347,84 +358,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
}
}
private void dataGridView_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if(e.ColumnIndex < 2 || e.RowIndex == -1) return;
int tag = (int)dataGridView.Rows[e.RowIndex].Cells[0].Value;
if(e.ColumnIndex == 2) //sectors
{
List<Sector> list = GetSectorsWithTag(tag, (int)dataGridView.Rows[e.RowIndex].Cells[2].Value);
if(list.Count > 0)
{
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedLinedefs();
List<Vector2D> points = new List<Vector2D>();
foreach(Sector s in list)
{
s.Selected = true;
foreach(Sidedef sd in s.Sidedefs)
{
points.Add(sd.Line.Start.Position);
points.Add(sd.Line.End.Position);
}
}
General.Map.Map.Update();
General.Editing.ChangeMode("SectorsMode");
ShowSelection(points);
}
}
else if(e.ColumnIndex == 3) //linedefs
{
List<Linedef> list = GetLinedefsWithTag(tag, (int)dataGridView.Rows[e.RowIndex].Cells[3].Value);
if(list.Count > 0)
{
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedLinedefs();
List<Vector2D> points = new List<Vector2D>();
foreach(Linedef l in list)
{
l.Selected = true;
points.Add(l.Start.Position);
points.Add(l.End.Position);
}
General.Map.Map.Update();
General.Editing.ChangeMode("LinedefsMode");
ShowSelection(points);
}
}
else if(e.ColumnIndex == 4) //things
{
List<Thing> list = GetThingsWithTag(tag, (int)dataGridView.Rows[e.RowIndex].Cells[4].Value);
if(list.Count > 0)
{
General.Map.Map.ClearSelectedThings();
List<Vector2D> points = new List<Vector2D>();
foreach(Thing t in list)
{
t.Selected = true;
Vector2D p = t.Position;
points.Add(p);
points.Add(p + new Vector2D(t.Size * 2.0f, t.Size * 2.0f));
points.Add(p + new Vector2D(t.Size * 2.0f, -t.Size * 2.0f));
points.Add(p + new Vector2D(-t.Size * 2.0f, t.Size * 2.0f));
points.Add(p + new Vector2D(-t.Size * 2.0f, -t.Size * 2.0f));
}
General.Map.Map.Update();
General.Editing.ChangeMode("ThingsMode");
ShowSelection(points);
}
}
}
private void TagStatisticsForm_FormClosing(object sender, FormClosingEventArgs e)
{
size = this.Size;

View file

@ -21,6 +21,6 @@ namespace CodeImp.DoomBuilder
public static class Clock
{
// This queries the system for the current time
public static float CurrentTime { get { return Configuration.Timer.ElapsedMilliseconds; } }
public static long CurrentTime { get { return Configuration.Timer.ElapsedMilliseconds; } }
}
}

View file

@ -3149,7 +3149,7 @@ namespace CodeImp.DoomBuilder.Map
{
Dictionary<uint, List<Sidedef>> storedsides = new Dictionary<uint, List<Sidedef>>(numsidedefs);
int originalsidescount = numsidedefs;
float starttime = Clock.CurrentTime;
long starttime = Clock.CurrentTime;
BeginAddRemove();
@ -3236,7 +3236,7 @@ namespace CodeImp.DoomBuilder.Map
EndAddRemove();
// Output info
float endtime = Clock.CurrentTime;
long endtime = Clock.CurrentTime;
float deltatimesec = (endtime - starttime) / 1000.0f;
float ratio = 100.0f - ((numsidedefs / (float)originalsidescount) * 100.0f);
General.WriteLogLine("Sidedefs compressed: " + numsidedefs + " remaining out of " + originalsidescount + " (" + ratio.ToString("########0.00") + "%) in " + deltatimesec.ToString("########0.00") + " seconds");

View file

@ -336,7 +336,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Highlight
if(General.Settings.AnimateVisualSelection)
{
float time = Clock.CurrentTime;
long time = Clock.CurrentTime;
highlightglow = (float)Math.Sin(time / 100.0f) * 0.1f + 0.4f;
highlightglowinv = -highlightglow + 0.8f;
}

View file

@ -1106,10 +1106,9 @@ namespace CodeImp.DoomBuilder.VisualModes
/// <summary>
/// While this mode is active, this is called continuously to process whatever needs processing.
/// </summary>
public override void OnProcess(float deltatime)
public override void OnProcess(float deltatime) { OnProcess((long)deltatime); } //mxd. DB2 compatibility
public override void OnProcess(long deltatime)
{
float multiplier;
base.OnProcess(deltatime);
// Camera vectors
@ -1120,6 +1119,7 @@ namespace CodeImp.DoomBuilder.VisualModes
Vector3D upvec = new Vector3D(0.0f, 0.0f, 1.0f);
// Move the camera
float multiplier;
if(General.Interface.ShiftState) multiplier = MOVE_SPEED_MULTIPLIER * 2.0f; else multiplier = MOVE_SPEED_MULTIPLIER;
if(keyforward) camdeltapos += camvec * cammovemul * General.Settings.MoveSpeed * multiplier * deltatime;
if(keybackward) camdeltapos -= camvec * cammovemul * General.Settings.MoveSpeed * multiplier * deltatime;

View file

@ -353,7 +353,7 @@ namespace CodeImp.DoomBuilder.VisualModes
if(!float.IsNaN(floorz) && !float.IsNaN(ceilz))
{
float voffset;
if(thing.IsFlipped)
if(thing.IsFlipped || info.Hangs)
{
float thingz = ceilz - Math.Max(0, Thing.Position.z) - Thing.Height;
voffset = -0.01f - General.Clamp(thingz, 0, ceilz - floorz);
@ -653,7 +653,7 @@ namespace CodeImp.DoomBuilder.VisualModes
return;
}
float time = Clock.CurrentTime;
long time = Clock.CurrentTime;
float rMin = Math.Min(lightPrimaryRadius, lightSecondaryRadius);
float rMax = Math.Max(lightPrimaryRadius, lightSecondaryRadius);
float diff = rMax - rMin;

View file

@ -90,6 +90,9 @@ namespace CodeImp.DoomBuilder.Windows
//mxd. This is sent by the background thread when sprites are loaded
SpriteDataLoaded = General.WM_USER + 3,
//mxd. This is sent by the background thread when all resources are loaded
ResourcesLoaded = General.WM_USER + 4,
}
#endregion
@ -157,7 +160,7 @@ namespace CodeImp.DoomBuilder.Windows
// Processing
private int processingcount;
private float lastupdatetime;
private long lastupdatetime;
// Updating
private int lockupdatecount;
@ -3933,6 +3936,12 @@ namespace CodeImp.DoomBuilder.Windows
}
break;
case (int)ThreadMessages.ResourcesLoaded: //mxd
string loadtime = Marshal.PtrToStringAuto(m.WParam);
Marshal.FreeCoTaskMem(m.WParam);
DisplayStatus(StatusType.Info, "Resources loaded in " + loadtime + " seconds");
break;
case General.WM_SYSCOMMAND:
// We don't want to open a menu when ALT is pressed
if(m.WParam.ToInt32() != General.SC_KEYMENU)
@ -4067,8 +4076,8 @@ namespace CodeImp.DoomBuilder.Windows
// Processor event
private void processor_Tick(object sender, EventArgs e)
{
float curtime = Clock.CurrentTime;
float deltatime = curtime - lastupdatetime;
long curtime = Clock.CurrentTime;
long deltatime = curtime - lastupdatetime;
lastupdatetime = curtime;
if ((General.Map != null) && (General.Editing.Mode != null))

View file

@ -54,7 +54,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Flash polygon
private FlatVertex[] flashpolygon;
private float flashintensity;
private float flashstarttime;
private long flashstarttime;
// Interface
protected bool editpressed;
@ -499,7 +499,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Processing
public override void OnProcess(float deltatime)
public override void OnProcess(long deltatime)
{
base.OnProcess(deltatime);
@ -507,7 +507,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(flashpolygon != null)
{
// Determine the intensity of the flash by time elapsed
float curtime = Clock.CurrentTime;
long curtime = Clock.CurrentTime;
flashintensity = 1f - ((curtime - flashstarttime) / FLASH_DURATION);
if(flashintensity > 0.0f)
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -49,8 +49,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
#region ================== Constants
// Object picking
private const float PICK_INTERVAL = 80.0f;
private const float PICK_INTERVAL_PAINT_SELECT = 10.0f; // biwa
private const long PICK_INTERVAL = 80;
private const long PICK_INTERVAL_PAINT_SELECT = 10; // biwa
private const float PICK_RANGE = 0.98f;
// Gravity
@ -67,7 +67,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Object picking
private VisualPickResult target;
private float lastpicktime;
private long lastpicktime;
private bool locktarget;
private bool useSelectionFromClassicMode;//mxd
private readonly Timer selectioninfoupdatetimer; //mxd
@ -1383,7 +1383,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Processing
public override void OnProcess(float deltatime)
public override void OnProcess(long deltatime)
{
float pickinterval = PICK_INTERVAL; // biwa
// Process things?

View file

@ -144,9 +144,9 @@ namespace CodeImp.DoomBuilder.TagExplorer
string comment = "";
string serachStr = tbSearch.Text.ToLowerInvariant();
List<int> filteredtags = new List<int>();
List<int> filteredactions = new List<int>();
List<int> filteredpolyobjects = new List<int>();
HashSet<int> filteredtags = new HashSet<int>();
HashSet<int> filteredactions = new HashSet<int>();
HashSet<int> filteredpolyobjects = new HashSet<int>();
GetSpecialValues(serachStr, ref filteredtags, ref filteredactions, ref filteredpolyobjects);
if(!udmf || filteredtags.Count > 0 || filteredactions.Count > 0 || filteredpolyobjects.Count > 0)
@ -333,23 +333,25 @@ namespace CodeImp.DoomBuilder.TagExplorer
{
if((showTags && s.Tag != 0) || (showActions && s.Effect > 0))
{
if(filteredtags.Count > 0 && !filteredtags.Contains(s.Tag)) continue;
if(filteredactions.Count > 0 && !filteredactions.Contains(s.Effect)) continue;
NodeInfo info = new NodeInfo(s);
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if(!hasComment && cbCommentsOnly.Checked) continue;
if(!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
for(int i = 0; i < s.Tags.Count; i++)
{
TreeNode node = new TreeNode(name, 3, 3) { Tag = info, ToolTipText = nodetooltip };
if(hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if(filteredtags.Count > 0 && !filteredtags.Contains(s.Tags[i])) continue;
if(info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
NodeInfo info = new NodeInfo(s, i);
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if(!hasComment && cbCommentsOnly.Checked) continue;
if(!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
{
TreeNode node = new TreeNode(name, 3, 3) { Tag = info, ToolTipText = nodetooltip };
if(hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if(info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
}
}
}
}
@ -449,31 +451,34 @@ namespace CodeImp.DoomBuilder.TagExplorer
{
if((showTags && l.Tag != 0) || (showActions && l.Action > 0))
{
if(filteredtags.Count > 0 && !filteredtags.Contains(l.Tag)) continue;
if(filteredactions.Count > 0 && !filteredactions.Contains(l.Action)) continue;
NodeInfo info = new NodeInfo(l);
if(filteredpolyobjects.Count > 0 && !filteredpolyobjects.Contains(info.PolyobjectNumber))
continue;
NodeInfo firstinfo = new NodeInfo(l, 0);
if(filteredpolyobjects.Count > 0 && !filteredpolyobjects.Contains(firstinfo.PolyobjectNumber)) continue;
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if(!hasComment && cbCommentsOnly.Checked) continue;
if(!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
for(int i = 0; i < l.Tags.Count; i++)
{
TreeNode node = new TreeNode(name, 5, 5) { Tag = info, ToolTipText = nodetooltip };
if(hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if(filteredtags.Count > 0 && !filteredtags.Contains(l.Tags[i])) continue;
if(info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
NodeInfo info = new NodeInfo(l, i);
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if(!hasComment && cbCommentsOnly.Checked) continue;
if(!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
{
TreeNode node = new TreeNode(name, 5, 5) { Tag = info, ToolTipText = nodetooltip };
if(hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if(info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
}
}
}
else if(currentDisplayMode == DISPLAY_POLYOBJECTS)
{
NodeInfo info = new NodeInfo(l);
NodeInfo info = new NodeInfo(l, 0);
if(info.PolyobjectNumber != int.MinValue && (filteredpolyobjects.Count == 0 || filteredpolyobjects.Contains(info.PolyobjectNumber)))
{
string name = info.GetName(ref comment, SortMode.SORT_BY_POLYOBJ_NUMBER);
@ -584,7 +589,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
}
//tag/action search
private static void GetSpecialValues(string serachstr, ref List<int> filteredtags, ref List<int> filteredactions, ref List<int> filteredpolyobjects)
private static void GetSpecialValues(string serachstr, ref HashSet<int> filteredtags, ref HashSet<int> filteredactions, ref HashSet<int> filteredpolyobjects)
{
if(serachstr.Length == 0) return;
@ -916,6 +921,9 @@ namespace CodeImp.DoomBuilder.TagExplorer
if(e.Label != null) info.Comment = e.Label;
e.Node.Text = info.GetName(ref comment, currentSortMode);
e.Node.ForeColor = string.IsNullOrEmpty(info.Comment) ? Color.Black : commentColor;
// Because of multiple tags, several nodes can link to the same sector/linedef
UpdateTree(false);
}
//It is called every time a dialog window closes.

View file

@ -34,12 +34,12 @@ namespace CodeImp.DoomBuilder.TagExplorer
defaultName = (tti != null ? tti.Title : "Thing");
}
public NodeInfo(Sector s)
public NodeInfo(Sector s, int tagindex)
{
type = NodeInfoType.SECTOR;
index = s.Index;
action = s.Effect;
tag = s.Tag;
tag = s.Tags[tagindex];
if(General.Map.Config.SectorEffects.ContainsKey(action))
{
@ -51,12 +51,12 @@ namespace CodeImp.DoomBuilder.TagExplorer
}
}
public NodeInfo(Linedef l)
public NodeInfo(Linedef l, int tagindex)
{
type = NodeInfoType.LINEDEF;
index = l.Index;
action = l.Action;
tag = l.Tag;
tag = l.Tags[tagindex];
polyobjnumber = ((l.Action > 0 && l.Action < 9) ? l.Args[0] : int.MinValue);
if(General.Map.Config.LinedefActions.ContainsKey(l.Action))

View file

@ -380,7 +380,7 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer
}
// Processing
public override void OnProcess(float deltatime)
public override void OnProcess(long deltatime)
{
base.OnProcess(deltatime);
if(DateTime.Now >= nextupdate)