patterncsharpMinor
Timecode class design
Viewed 0 times
timecodedesignclass
Problem
I've created a
```
///
/// Immutable timecode.
///
///
/// Represents a timecode in hh:mm:ss:ff format. Rolls over at the 24 hour mark.
///
[Serializable]
public class Timecode
{
private static readonly Regex TimecodeRegex = new Regex(@"^(?\d{1,2}):(?\d{1,2}):(?\d{1,2}):(?\d{1,3})$", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
private int totalFrames;
private short frameRate;
public Timecode(int totalFrames, short frameRate = 25)
{
if (frameRate
/// The hours segment of the timecode.
///
public int Hours
{
get
{
return (int)this.totalFrames / this.frameRate / 60 / 60;
}
}
///
/// The minutes segment of the timecode.
///
public int Minutes
{
get
{
return (int)this.totalFrames / this.frameRate / 60 % 60;
}
}
///
/// The seconds segment of the timecode.
///
public int Seconds
{
get
{
return (int)this.totalFrames / this.frameRate % 60;
}
}
///
/// The frames segment of the timecode.
///
public int Frames
{
get
{
return (int)this.totalFrames % this.frameRate;
}
}
///
/// The total number of frames for this timecode.
///
public int TotalFrames
{
get
{
return this.totalFrames;
}
}
///
/// The framerate of this timecode.
///
publ
Timecode class. The "timecode" that I'm trying to represent is a timecode that is used in video editing quite often, and is seen displayed in the format "hh:mm:ss:ff", or 10:00:05:24, for example ("ff" = frames").```
///
/// Immutable timecode.
///
///
/// Represents a timecode in hh:mm:ss:ff format. Rolls over at the 24 hour mark.
///
[Serializable]
public class Timecode
{
private static readonly Regex TimecodeRegex = new Regex(@"^(?\d{1,2}):(?\d{1,2}):(?\d{1,2}):(?\d{1,3})$", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
private int totalFrames;
private short frameRate;
public Timecode(int totalFrames, short frameRate = 25)
{
if (frameRate
/// The hours segment of the timecode.
///
public int Hours
{
get
{
return (int)this.totalFrames / this.frameRate / 60 / 60;
}
}
///
/// The minutes segment of the timecode.
///
public int Minutes
{
get
{
return (int)this.totalFrames / this.frameRate / 60 % 60;
}
}
///
/// The seconds segment of the timecode.
///
public int Seconds
{
get
{
return (int)this.totalFrames / this.frameRate % 60;
}
}
///
/// The frames segment of the timecode.
///
public int Frames
{
get
{
return (int)this.totalFrames % this.frameRate;
}
}
///
/// The total number of frames for this timecode.
///
public int TotalFrames
{
get
{
return this.totalFrames;
}
}
///
/// The framerate of this timecode.
///
publ
Solution
Logic
At a lot of places in your code is some kind of calculation taking place which could be reduced by precalculation at the only point where changes can happen, inside the constructor.
Changing the properties to autoimplemented properties with private setters like
they can be filled like
and after changing the
and a simplified
I will try to answer your questions tomorrow, if not already done.
At a lot of places in your code is some kind of calculation taking place which could be reduced by precalculation at the only point where changes can happen, inside the constructor.
Changing the properties to autoimplemented properties with private setters like
///
/// The hours segment of the timecode.
///
public int Hours { get; private set; }
///
/// The seconds segment of the timecode.
///
public int Seconds { get; private set; }they can be filled like
public Timecode(int hours, int minutes, int seconds, int frames, short frameRate = 25)
{
frames += seconds * frameRate;
frames += minutes * 60 * frameRate;
frames += hours * 3600 * frameRate;
TotalFrames = frames % FramesPerDay(frameRate);
FrameRate = frameRate;
Hours = hours;
Minutes = minutes;
Seconds= seconds;
}and after changing the
TotalSeconds() method to a property public Timecode(int totalFrames, short frameRate = 25)
{
if (frameRate <= 0) throw new ArgumentOutOfRangeException("frameRate");
TotalFrames = totalFrames % FramesPerDay(frameRate);
FrameRate = frameRate;
TotalSeconds = (float)TotalFrames / (float)FrameRate; ;
Frames = (int)totalFrames % frameRate;
Seconds = (int)TotalFrames / FrameRate / 60 % 60;
Minutes = (int)TotalFrames / FrameRate / 60 % 60;
Hours = (int)TotalFrames / FrameRate / 60 / 60;
}and a simplified
ToString() public override string ToString()
{
return string.Format("{0}:{1}:{2}:{3}",
PadTimecodeUnit(Hours),
PadTimecodeUnit(Minutes),
PadTimecodeUnit(Seconds),
PadTimecodeUnit(Frames));
}I will try to answer your questions tomorrow, if not already done.
Code Snippets
/// <summary>
/// The hours segment of the timecode.
/// </summary>
public int Hours { get; private set; }
/// <summary>
/// The seconds segment of the timecode.
/// </summary>
public int Seconds { get; private set; }public Timecode(int hours, int minutes, int seconds, int frames, short frameRate = 25)
{
frames += seconds * frameRate;
frames += minutes * 60 * frameRate;
frames += hours * 3600 * frameRate;
TotalFrames = frames % FramesPerDay(frameRate);
FrameRate = frameRate;
Hours = hours;
Minutes = minutes;
Seconds= seconds;
}public Timecode(int totalFrames, short frameRate = 25)
{
if (frameRate <= 0) throw new ArgumentOutOfRangeException("frameRate");
TotalFrames = totalFrames % FramesPerDay(frameRate);
FrameRate = frameRate;
TotalSeconds = (float)TotalFrames / (float)FrameRate; ;
Frames = (int)totalFrames % frameRate;
Seconds = (int)TotalFrames / FrameRate / 60 % 60;
Minutes = (int)TotalFrames / FrameRate / 60 % 60;
Hours = (int)TotalFrames / FrameRate / 60 / 60;
}public override string ToString()
{
return string.Format("{0}:{1}:{2}:{3}",
PadTimecodeUnit(Hours),
PadTimecodeUnit(Minutes),
PadTimecodeUnit(Seconds),
PadTimecodeUnit(Frames));
}Context
StackExchange Code Review Q#77644, answer score: 4
Revisions (0)
No revisions yet.