Calendar
Mo | Tu | We | Th | Fr | Sa | Su |
---|
25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 |
Archive
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2019
- 2020
|
Website may be up and down over next few months. I'm currently doing a complete overhaul of everything.
Going back to simple individual .htm pages, new overall site theme, sanitizing and cleaning up html of all
pages and blog posts, attempting to implement a new tooling and publishing system etc etc.
Takes in an array of floats representing pixels ordered left to right top to bottom. Width & height arguments specify the image dimensions. /// <summary>
/// Smoothens out the image.
/// </summary>
/// <param name="image">The source image.</param>
/// <exception cref="ArgumentNullException"><paramref name="getPixel"/> or <paramref name="setPixel"/> is <see langword="null" />.</exception>
public static void Smoothen(this float[] image, int width, int height, Func<int, int, float> getPixel, Action<int, int, float> setPixel, float smoothinValue = 9f)
{
if (getPixel == null)
{
throw new ArgumentNullException("getPixel");
}
if (setPixel == null)
{
throw new ArgumentNullException("setPixel");
}
for (var x = 1; x < width - 1; ++x)
{
for (var y = 1; y < height - 1; ++y)
{
var total = 0f;
for (var u = -1; u <= 1; u++)
{
for (var v = -1; v <= 1; v++)
{
total += getPixel(x + u, y + v);
}
}
setPixel(x, y, total / smoothinValue);
}
}
}
f23c8083-231a-402e-8106-dfb0d004f568|0|.0
The fallowing script allows you to control fog settings on a per camera basis, allowing you to use say green fog for one camera but red fog for another camera.
Unity 5 package demo is available here CameraFog.unitypackage (46.66 kb)
CameraFog.cs script
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CameraFog.cs" company="Codefarts">
// Copyright (c) 2012 Codefarts
// All rights reserved.
// contact@codefarts.com
// http://www.codefarts.com
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
// Per-camera fog
// This is a simple class that, when added to a GameObject with a camera, allows you to control the fog settings for that camera separately from the global ones.
// I'd love to hear from you if you do anything cool with this or have any suggestions :)
// Original author: http://wiki.unity3d.com/index.php/User:Tenebrous
// Author website as of 2015: www.tenebrous.co.uk
// Source: http://wiki.unity3d.com/index.php/CameraFog
namespace Codefarts.GeneralTools.Scripts.Camera
{
using UnityEngine;
/// <summary>
/// Modifies a camera to allows you to control the fog settings for that camera separately from the global scene fog or other cameras.
/// </summary>
[RequireComponent(typeof(Camera))]
[ExecuteInEditMode]
public class CameraFog : MonoBehaviour
{
/// <summary>
/// The enabled state weather or not fog will be visible.
/// </summary>
public bool Enabled;
/// <summary>
/// The start distance from the camera where the fog will be drawn.
/// </summary>
public float StartDistance;
/// <summary>
/// The end distance from the camera where the fog will be drawn.
/// </summary>
public float EndDistance;
/// <summary>
/// The fog mode that controls how the fog is rendered.
/// </summary>
public FogMode Mode;
/// <summary>
/// The density of the fog that is rendered.
/// </summary>
public float Density;
/// <summary>
/// The fog color.
/// </summary>
public Color Color;
/// <summary>
/// Stores the pre-render state of the start distance.
/// </summary>
private float _startDistance;
/// <summary>
/// Stores the pre-render state of the end distance.
/// </summary>
private float _endDistance;
/// <summary>
/// Stores the pre-render state of the fog mode.
/// </summary>
private FogMode _mode;
/// <summary>
/// Stores the pre-render state of the density.
/// </summary>
private float _density;
/// <summary>
/// Stores the pre-render state of the fog color.
/// </summary>
private Color _color;
/// <summary>
/// Stores the pre-render state wheather or not the fog is enabled.
/// </summary>
private bool _enabled;
/// <summary>
/// Event that is fired before any camera starts rendering.
/// </summary>
private void OnPreRender()
{
this._startDistance = RenderSettings.fogStartDistance;
this._endDistance = RenderSettings.fogEndDistance;
this._mode = RenderSettings.fogMode;
this._density = RenderSettings.fogDensity;
this._color = RenderSettings.fogColor;
this._enabled = RenderSettings.fog;
RenderSettings.fog = this.Enabled;
RenderSettings.fogStartDistance = this.StartDistance;
RenderSettings.fogEndDistance = this.EndDistance;
RenderSettings.fogMode = this.Mode;
RenderSettings.fogDensity = this.Density;
RenderSettings.fogColor = this.Color;
}
/// <summary>
/// Event that is fired after any camera finishes rendering.
/// </summary>
private void OnPostRender()
{
RenderSettings.fog = this._enabled;
RenderSettings.fogStartDistance = this._startDistance;
RenderSettings.fogEndDistance = this._endDistance;
RenderSettings.fogMode = this._mode;
RenderSettings.fogDensity = this._density;
RenderSettings.fogColor = this._color;
}
}
}
3e68139e-e598-4f81-95a0-97e5ff0eeec9|0|.0
With the introduction to Unity 5 there comes some api changes. Specifically this foot note was interesting “[2] in Unity5 we also cache the transform component on the c# side, so there should no longer be a performance reason to cache the transform component yourself.”
I decided to test it out by writing a few performance test scripts and comparing performance numbers. Below is a screen shot of my results along with the scripts used.
As you can see caching a reference to the transform component in the Start method then using that reference is still faster then calling “this.transform” directly albeit only slightly by about 10-20 ticks. And calling “this.GetComponent<Transform>()” is almost twice as slow.
The code for the PerformanceTesting class is availible here.
TransformCachedGetComponentPerformance script
using UnityEngine;
public class TransformCachedGetComponentPerformance : MonoBehaviour
{
private Transform reference;
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
public void Awake()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Create("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
}
/// <summary>
/// Start is called just before any of the Update methods is called the first time.
/// </summary>
public void Start()
{
this.reference = this.GetComponent<Transform>();
}
/// <summary>
/// Update is called every frame, if the MonoBehaviour is enabled.
/// </summary>
public void Update()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Start("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
var rnd = new System.Random();
this.reference.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
#if PERFORMANCE
perf.Stop("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
}
}
TransformGetComponentPerformance script
using UnityEngine;
public class TransformGetComponentPerformance : MonoBehaviour
{
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
public void Awake()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Create("UnityTesting/TransformGetComponentPerformance/Update");
#endif
}
/// <summary>
/// Update is called every frame, if the MonoBehaviour is enabled.
/// </summary>
public void Update()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Start("UnityTesting/TransformGetComponentPerformance/Update");
#endif
var rnd = new System.Random();
this.GetComponent<Transform>().localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
#if PERFORMANCE
perf.Stop("UnityTesting/TransformGetComponentPerformance/Update");
#endif
}
}
TransformFieldPerformance script
using UnityEngine;
public class TransformFieldPerformance : MonoBehaviour
{
/// <summary>
/// Awake is called when the script instance is being loaded.
/// </summary>
public void Awake()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Create("UnityTesting/TransformFieldPerformance/Update");
#endif
}
/// <summary>
/// Update is called every frame, if the MonoBehaviour is enabled.
/// </summary>
public void Update()
{
#if PERFORMANCE
var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
perf.Start("UnityTesting/TransformFieldPerformance/Update");
#endif
var rnd = new System.Random();
this.transform.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
#if PERFORMANCE
perf.Stop("UnityTesting/TransformFieldPerformance/Update");
#endif
}
}
0631a2dd-08a4-4b60-b9fa-0f8221b4adb9|2|5.0
The fallowing code snip is designed to take in a flat list of file paths (or similar data) and produce a hierarchy of tree nodes representing those file paths.
/// <summary>
/// Constructs a nested hierarchy of types from a flat list of source types.
/// </summary>
/// <typeparam name="TSource">The source type of the flat list that is to be converted.</typeparam>
/// <typeparam name="TReturn">The type that will be returned.</typeparam>
/// <typeparam name="TPart">The type of the art type.</typeparam>
/// <param name="sourceItems">The source items to be converted.</param>
/// <param name="getParts">A callback function that returns a array of <see cref="TPart"/>.</param>
/// <param name="comparePart">The compare part callback.</param>
/// <param name="getChildren">The get children callback.</param>
/// <param name="addChild">The add child callback.</param>
/// <param name="createItem">The create item callback.</param>
/// <returns>Returns an collection of <see cref="TReturn"/> representing the hierarchy.</returns>
/// <exception cref="Exception">A delegate callback throws an exception. </exception>
private static IEnumerable<TReturn> ToHierarchy<TSource, TReturn, TPart>(
IEnumerable<TSource> sourceItems,
Func<TSource, TPart[]> getParts,
Func<TReturn, TPart, bool> comparePart,
Func<TReturn, IEnumerable<TReturn>> getChildren,
Action<IEnumerable<TReturn>, TReturn> addChild,
Func<TPart[], int, TSource, TReturn> createItem)
{
var treeModels = new List<TReturn>();
foreach (var keyName in sourceItems)
{
IEnumerable<TReturn> items = treeModels;
var parts = getParts(keyName);
for (var partIndex = 0; partIndex < parts.Length; partIndex++)
{
var node = items.FirstOrDefault(x => comparePart(x, parts[partIndex]));
if (node != null)
{
items = getChildren(node);
continue;
}
var model = createItem(parts, partIndex, keyName);
addChild(items, model);
items = getChildren(model);
}
}
return treeModels;
}
An example of how one could use the ToHierarchy method would be like this …
var separator = new[] { Path.AltDirectorySeparatorChar.ToString(CultureInfo.InvariantCulture) };
// paths varible could be something from Directory.GetDirectories method for example.
var nodes = ToHierarchy<string, TreeViewNode, string>(
paths.OrderBy(x => x),
x => x.Split(separator, StringSplitOptions.RemoveEmptyEntries),
(r, p) => string.CompareOrdinal(r.Name, p) == 0,
r => r.Nodes,
(r, c) => ((List<TreeViewNode>)r).Add(c),
this.CreateTreeNode);
private TreeViewNode CreateTreeNode(string[] parts, int index, string source)
{
var node = new TreeViewNode() { Name = parts[index] };
node.Value = string.Join(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), parts, 0, index + 1);
if (index == parts.Length - 1)
{
node.Name = Path.GetFileName(source);
}
node.IsFile = File.Exists(node.Value);
return node;
}
Where paths is a array of file paths from say Directory.GetFiles.
3bebbb17-378e-4ffb-b2dd-e42a8fb57745|0|.0
Source: http://stackoverflow.com/questions/616718/how-do-i-get-common-file-type-icons-in-c public static class FileIcon
{
[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
private const uint SHGFI_ICON = 0x100;
private const uint SHGFI_LARGEICON = 0x0; // 'Large icon
private const uint SHGFI_SMALLICON = 0x1; // 'Small icon
public static System.Drawing.Icon GetLargeIcon(string file)
{
var shinfo = new SHFILEINFO();
var hImgLarge = SHGetFileInfo(file, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), FileIcon.SHGFI_ICON | FileIcon.SHGFI_LARGEICON);
return System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
public static System.Drawing.Icon GetSmallIcon(string file)
{
var shinfo = new SHFILEINFO();
var hImgLarge = SHGetFileInfo(file, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), FileIcon.SHGFI_ICON | FileIcon.SHGFI_SMALLICON);
return System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
}
22617284-c3d3-4a4f-8daf-00924d264f58|0|.0
Did you know that the GUI class has a matrix property that you can use to rotate and scale your gui elements.
The sample behavior that is provided below will scale and rotate a gui label in the center of the screen.
public class GuiMatrixDemo : MonoBehaviour
{
private float rotation;
/// <summary>
/// OnGUI is called for rendering and handling GUI events.
/// </summary>
public void OnGUI()
{
var matrix = GUI.matrix;
GUI.Label(new Rect(5, 5, 100, 20), "before matrix");
this.rotation += 15f * Time.deltaTime;
var scale = Mathf.Clamp((float)Math.Sin(Time.time) + 1 * 2, 1, 3);
GUI.matrix = Matrix4x4.TRS(new Vector3(Screen.width / 2, Screen.height / 2, 0), Quaternion.Euler(0, 0, this.rotation), Vector3.one * scale);
var size = GUI.skin.label.CalcSize(new GUIContent("test string"));
var rect = new Rect((-size.x / 2f), (-size.y / 2f), size.x, size.y);
GUI.Label(rect, "test string");
GUI.matrix = matrix;
GUI.Label(new Rect(5, 25, 100, 20), "after matrix");
}
}
2936e197-d8e8-4a41-b1e1-b28f52910f69|0|.0
If you have some editor scripts and you want to detect weather or not unity has compiled your scripts you can try this simple method. Created a private class within your editor window and declare a field of that private class. public class YourEditor : EditorWindow
{
private RecompileClass recompile;
private class RecompileClass
{
}
}
In the OnGUI method (or where appropriate) perform a check to see if the field is null. If it’s null you can assume that unity compiled your scripts again so do what you need to do is create a new instance of the private class and assign it to the field.
public class YourEditor : EditorWindow
{
private RecompileClass recompile;
private class RecompileClass
{
}
public void OnGUI()
{
// check if recompile variable is null
if (this.recompile == null )
{
// if yes assume recompile then create a reference to a recompile class
this.recompile = new RecompileClass();
// do what you need to do here after detecting a recompile
}
// do regular stuff here
}
}
The next time unity recompiles your scripts the field will loose it’s reference and will be null again.
7a47664e-c7f9-40c0-863a-031034f1e57e|0|.0
using System;
using System.Collections.Generic;
/// <summary>
/// Implements a generic equality comparer that uses a callback to perform the comparison.
/// </summary>
/// <typeparam name="T">The type we want to compare.</typeparam>
public class EqualityComparerCallback<T> : IEqualityComparer<T>
{
/// <summary>
/// Holds a reference to the callback that handles comparisons.
/// </summary>
private readonly Func<T, T, bool> function;
/// <summary>
/// Holds a reference to the callback used to calculate hash codes.
/// </summary>
private Func<T, int> hashFunction;
/// <summary>
/// Initializes a new instance of the <see cref="EqualityComparerCallback{T}"/> class.
/// </summary>
/// <param name="func">
/// The callback function that will do the comparing.
/// </param>
/// <exception cref="ArgumentNullException">
/// Throws a <see cref="ArgumentNullException"/> if the <see cref="func"/> parameter is null.
/// </exception>
public EqualityComparerCallback(Func<T, T, bool> func)
{
if (func == null)
{
throw new ArgumentNullException("func");
}
this.function = func;
}
/// <summary>
/// Initializes a new instance of the <see cref="EqualityComparerCallback{T}"/> class.
/// </summary>
/// <param name="func">
/// The callback function that will do the comparing.
/// </param>
/// <param name="hash">
/// The callback function that will return the hash code.
/// </param>
public EqualityComparerCallback(Func<T, T, bool> func, Func<T, int> hash)
: this(func)
{
this.hashFunction = hash;
}
/// <summary>
/// Gets or sets the callback function to use to compute the hash.
/// </summary>
public Func<T, int> HashFunction
{
get
{
return this.hashFunction;
}
set
{
this.hashFunction = value;
}
}
/// <summary>
/// Provides a static method for returning a <see cref="EqualityComparerCallback{T}"/> type.
/// </summary>
/// <param name="func">
/// The callback function that will do the comparing.
/// </param>
/// <returns>Returns a new instance of a <see cref="EqualityComparerCallback{T}"/> type.</returns>
public static IEqualityComparer<T> Compare(Func<T, T, bool> func)
{
return new EqualityComparerCallback<T>(func);
}
/// <summary>
/// Determines whether the specified object instances are considered equal.
/// </summary>
/// <param name="x">The first object to compare.</param>
/// <param name="y">The second object to compare.</param>
/// <returns>True if the objects are considered equal otherwise, false. If both objA and objB are null, the method returns true.</returns>
public bool Equals(T x, T y)
{
return this.function(x, y);
}
/// <summary>
/// The get hash code for a object.
/// </summary>
/// <param name="obj">
/// The object whose hash code will be computed.
/// </param>
/// <returns>
/// Returns a <see cref="int"/> value representing the hash code.
/// </returns>
/// <remarks>If no callback function was set for the <see cref="HashFunction"/> the object default <see cref="GetHashCode"/> method will be used.</remarks>
public int GetHashCode(T obj)
{
if (this.hashFunction == null)
{
return obj.GetHashCode();
}
return this.hashFunction(obj);
}
}
A usage scenario
// build a list of unique categories
var list = new List<string>();
foreach (var rule in this.rules)
{
if (string.IsNullOrEmpty(rule.Category ?? string.Empty))
{
continue;
}
// check if already exists
if (list.Contains(rule.Category, new EqualityComparerCallback<string>((a, b) => a.Trim() == b.Trim())))
{
continue;
}
}
return list.ToArray();
333443f0-1633-4575-a8cf-c61d4e92f924|0|.0
Simple solution to get a MIME type from a file extension. Source –> http://stackoverflow.com/a/7161265/341706
public static class MIMEAssistant
{
private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
{
{"ai", "application/postscript"},
{"aif", "audio/x-aiff"},
{"aifc", "audio/x-aiff"},
{"aiff", "audio/x-aiff"},
{"asc", "text/plain"},
{"atom", "application/atom+xml"},
{"au", "audio/basic"},
{"avi", "video/x-msvideo"},
{"bcpio", "application/x-bcpio"},
{"bin", "application/octet-stream"},
{"bmp", "image/bmp"},
{"cdf", "application/x-netcdf"},
{"cgm", "image/cgm"},
{"class", "application/octet-stream"},
{"cpio", "application/x-cpio"},
{"cpt", "application/mac-compactpro"},
{"csh", "application/x-csh"},
{"css", "text/css"},
{"dcr", "application/x-director"},
{"dif", "video/x-dv"},
{"dir", "application/x-director"},
{"djv", "image/vnd.djvu"},
{"djvu", "image/vnd.djvu"},
{"dll", "application/octet-stream"},
{"dmg", "application/octet-stream"},
{"dms", "application/octet-stream"},
{"doc", "application/msword"},
{"docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
{"dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
{"docm","application/vnd.ms-word.document.macroEnabled.12"},
{"dotm","application/vnd.ms-word.template.macroEnabled.12"},
{"dtd", "application/xml-dtd"},
{"dv", "video/x-dv"},
{"dvi", "application/x-dvi"},
{"dxr", "application/x-director"},
{"eps", "application/postscript"},
{"etx", "text/x-setext"},
{"exe", "application/octet-stream"},
{"ez", "application/andrew-inset"},
{"gif", "image/gif"},
{"gram", "application/srgs"},
{"grxml", "application/srgs+xml"},
{"gtar", "application/x-gtar"},
{"hdf", "application/x-hdf"},
{"hqx", "application/mac-binhex40"},
{"htm", "text/html"},
{"html", "text/html"},
{"ice", "x-conference/x-cooltalk"},
{"ico", "image/x-icon"},
{"ics", "text/calendar"},
{"ief", "image/ief"},
{"ifb", "text/calendar"},
{"iges", "model/iges"},
{"igs", "model/iges"},
{"jnlp", "application/x-java-jnlp-file"},
{"jp2", "image/jp2"},
{"jpe", "image/jpeg"},
{"jpeg", "image/jpeg"},
{"jpg", "image/jpeg"},
{"js", "application/x-javascript"},
{"kar", "audio/midi"},
{"latex", "application/x-latex"},
{"lha", "application/octet-stream"},
{"lzh", "application/octet-stream"},
{"m3u", "audio/x-mpegurl"},
{"m4a", "audio/mp4a-latm"},
{"m4b", "audio/mp4a-latm"},
{"m4p", "audio/mp4a-latm"},
{"m4u", "video/vnd.mpegurl"},
{"m4v", "video/x-m4v"},
{"mac", "image/x-macpaint"},
{"man", "application/x-troff-man"},
{"mathml", "application/mathml+xml"},
{"me", "application/x-troff-me"},
{"mesh", "model/mesh"},
{"mid", "audio/midi"},
{"midi", "audio/midi"},
{"mif", "application/vnd.mif"},
{"mov", "video/quicktime"},
{"movie", "video/x-sgi-movie"},
{"mp2", "audio/mpeg"},
{"mp3", "audio/mpeg"},
{"mp4", "video/mp4"},
{"mpe", "video/mpeg"},
{"mpeg", "video/mpeg"},
{"mpg", "video/mpeg"},
{"mpga", "audio/mpeg"},
{"ms", "application/x-troff-ms"},
{"msh", "model/mesh"},
{"mxu", "video/vnd.mpegurl"},
{"nc", "application/x-netcdf"},
{"oda", "application/oda"},
{"ogg", "application/ogg"},
{"pbm", "image/x-portable-bitmap"},
{"pct", "image/pict"},
{"pdb", "chemical/x-pdb"},
{"pdf", "application/pdf"},
{"pgm", "image/x-portable-graymap"},
{"pgn", "application/x-chess-pgn"},
{"pic", "image/pict"},
{"pict", "image/pict"},
{"png", "image/png"},
{"pnm", "image/x-portable-anymap"},
{"pnt", "image/x-macpaint"},
{"pntg", "image/x-macpaint"},
{"ppm", "image/x-portable-pixmap"},
{"ppt", "application/vnd.ms-powerpoint"},
{"pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"},
{"potx","application/vnd.openxmlformats-officedocument.presentationml.template"},
{"ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
{"ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12"},
{"pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
{"potm","application/vnd.ms-powerpoint.template.macroEnabled.12"},
{"ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
{"ps", "application/postscript"},
{"qt", "video/quicktime"},
{"qti", "image/x-quicktime"},
{"qtif", "image/x-quicktime"},
{"ra", "audio/x-pn-realaudio"},
{"ram", "audio/x-pn-realaudio"},
{"ras", "image/x-cmu-raster"},
{"rdf", "application/rdf+xml"},
{"rgb", "image/x-rgb"},
{"rm", "application/vnd.rn-realmedia"},
{"roff", "application/x-troff"},
{"rtf", "text/rtf"},
{"rtx", "text/richtext"},
{"sgm", "text/sgml"},
{"sgml", "text/sgml"},
{"sh", "application/x-sh"},
{"shar", "application/x-shar"},
{"silo", "model/mesh"},
{"sit", "application/x-stuffit"},
{"skd", "application/x-koan"},
{"skm", "application/x-koan"},
{"skp", "application/x-koan"},
{"skt", "application/x-koan"},
{"smi", "application/smil"},
{"smil", "application/smil"},
{"snd", "audio/basic"},
{"so", "application/octet-stream"},
{"spl", "application/x-futuresplash"},
{"src", "application/x-wais-source"},
{"sv4cpio", "application/x-sv4cpio"},
{"sv4crc", "application/x-sv4crc"},
{"svg", "image/svg+xml"},
{"swf", "application/x-shockwave-flash"},
{"t", "application/x-troff"},
{"tar", "application/x-tar"},
{"tcl", "application/x-tcl"},
{"tex", "application/x-tex"},
{"texi", "application/x-texinfo"},
{"texinfo", "application/x-texinfo"},
{"tif", "image/tiff"},
{"tiff", "image/tiff"},
{"tr", "application/x-troff"},
{"tsv", "text/tab-separated-values"},
{"txt", "text/plain"},
{"ustar", "application/x-ustar"},
{"vcd", "application/x-cdlink"},
{"vrml", "model/vrml"},
{"vxml", "application/voicexml+xml"},
{"wav", "audio/x-wav"},
{"wbmp", "image/vnd.wap.wbmp"},
{"wbmxl", "application/vnd.wap.wbxml"},
{"wml", "text/vnd.wap.wml"},
{"wmlc", "application/vnd.wap.wmlc"},
{"wmls", "text/vnd.wap.wmlscript"},
{"wmlsc", "application/vnd.wap.wmlscriptc"},
{"wrl", "model/vrml"},
{"xbm", "image/x-xbitmap"},
{"xht", "application/xhtml+xml"},
{"xhtml", "application/xhtml+xml"},
{"xls", "application/vnd.ms-excel"},
{"xml", "application/xml"},
{"xpm", "image/x-xpixmap"},
{"xsl", "application/xml"},
{"xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{"xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
{"xlsm","application/vnd.ms-excel.sheet.macroEnabled.12"},
{"xltm","application/vnd.ms-excel.template.macroEnabled.12"},
{"xlam","application/vnd.ms-excel.addin.macroEnabled.12"},
{"xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
{"xslt", "application/xslt+xml"},
{"xul", "application/vnd.mozilla.xul+xml"},
{"xwd", "image/x-xwindowdump"},
{"xyz", "chemical/x-xyz"},
{"zip", "application/zip"}
};
public static string GetMIMEType(string fileName)
{
if (Path.GetExtension(fileName).Length > 1 && MIMETypesDictionary.ContainsKey(Path.GetExtension(fileName).Remove(0, 1)))
{
return MIMETypesDictionary[Path.GetExtension(fileName).Remove(0, 1)];
}
return "unknown/unknown";
}
}
c6353f07-f077-44d3-9f38-8db47d14e14a|0|.0
I needed a quick file caching solution and here is what I came up with … using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
/// <summary>
/// Provides a file model used by the <see cref="FileCache"/> type.
/// </summary>
public class FileModel
{
/// <summary>
/// Gets or sets information about the file.
/// </summary>
public FileInfo Info { get; set; }
/// <summary>
/// Gets or sets the last time that the file had it's contents cached.
/// </summary>
public DateTime LastUpdate { get; set; }
/// <summary>
/// Gets or sets the file content for the file.
/// </summary>
public StringBuilder Data { get; set; }
}
/// <summary>
/// Provides a caching for file content based on file extensions.
/// </summary>
public class FileCache
{
/// <summary>
/// Holds a singleton instance of a <see cref="FileCache"/> type.
/// </summary>
private static FileCache singleton;
/// <summary>
/// Used to hold the contents of the files.
/// </summary>
private readonly Dictionary<string, FileModel> files;
/// <summary>
/// Holds the list of extensions for files that will have there contents cached.
/// </summary>
private readonly List<string> extensions;
/// <summary>
/// Gets or sets a time value used to determine if a files content should be read again.
/// </summary>
public TimeSpan CacheTime { get; set; }
/// <summary>
/// Gets a list of file extension that will have there contents cached.
/// </summary>
public List<string> Extensions
{
get
{
return this.extensions;
}
}
/// <summary>
/// Default constructor.
/// </summary>
public FileCache()
{
this.files = new Dictionary<string, FileModel>();
this.extensions = new List<string>();
this.extensions.AddRange(new[] { ".htm" });
this.CacheTime = TimeSpan.FromSeconds(2);
}
/// <summary>
/// Provides a helper method for retrieving a file.
/// </summary>
/// <param name="path">The path to the file.</param>
/// <returns>Returns a <see cref="FileModel"/> type containing information about the file.</returns>
public static FileModel GetFile(string path)
{
return Instance.Get(path);
}
/// <summary>
/// Provides a helper method for retrieving a file.
/// </summary>
/// <param name="path">The path to the file.</param>
/// <returns>Returns a <see cref="FileModel"/> type containing information about the file.</returns>
public FileModel Get(string path)
{
// if file does not exit just return null
if (!File.Exists(path))
{
return null;
}
// check if file already exists in the cache
FileModel model;
if (this.files.ContainsKey(path))
{
// get existing entry
model = this.files[path];
}
else
{
// add new entry
model = new FileModel { LastUpdate = DateTime.Now, Info = new FileInfo(path) };
this.files.Add(path, model);
}
// check to cache file data
if (this.extensions.Contains(model.Info.Extension))
{
// not data has been read yet OR (the current time has surpassed the last update time plus the cache time AND
// the current time is greater then the last write time ) we can read the contents of the file
if (model.Data == null || (DateTime.Now > model.LastUpdate + this.CacheTime && DateTime.Now > model.Info.LastWriteTime))
{
model.Data = new StringBuilder(File.ReadAllText(model.Info.FullName));
}
}
// return the modal data
return model;
}
/// <summary>
/// Gets a singleton instance of a <see cref="FileCache"/> type.
/// </summary>
public static FileCache Instance
{
get
{
return singleton ?? (singleton = new FileCache());
}
}
}
38133126-9626-4b25-9266-91f4b3b6ce51|1|5.0
|
|