refactoring about resource file management.
画像などのリソースファイル読み込みの整理など
@@ -12,7 +12,6 @@ | ||
12 | 12 | using System.Drawing.Imaging; |
13 | 13 | using System.Runtime.InteropServices; |
14 | 14 | using System.Diagnostics; |
15 | -using nft.framework.util; | |
16 | 15 | using nft.framework.plugin; |
17 | 16 | |
18 | 17 | namespace nft.contributions.game { |
@@ -36,7 +35,7 @@ | ||
36 | 35 | float hr = param[KEY_HORZ_SCALING, 1.0f]; |
37 | 36 | ColorChannel cc = (ColorChannel)Enum.Parse(typeof(ColorChannel), param[KEY_COLOR_CHANNEL]); |
38 | 37 | int sea = param[KEY_SEA_LEVEL_HEIGHT, 0]; |
39 | - ImageRef iref = LocalFileImageRef.FromFile(src); | |
38 | + ImageRef iref = ImageRef.FromFile(src); | |
40 | 39 | return new BitmapSourceTerrainMap(iref, hr, vr, cc, sea); |
41 | 40 | } |
42 | 41 | #endregion |
@@ -3,7 +3,6 @@ | ||
3 | 3 | using System.Text; |
4 | 4 | using nft.ui.mainframe; |
5 | 5 | using nft.framework.drawing; |
6 | -using nft.framework.util; | |
7 | 6 | using nft.framework; |
8 | 7 | using System.Drawing; |
9 | 8 | using System.IO; |
@@ -18,7 +17,7 @@ | ||
18 | 17 | private ISurfaceOld surface; |
19 | 18 | |
20 | 19 | public TestViewDrawer() { |
21 | - imgRef = LocalFileImageRef.FromFile(ImagePath); | |
20 | + imgRef = ImageRef.FromFile(ImagePath); | |
22 | 21 | DoubleBuffered = false; |
23 | 22 | surface = null; |
24 | 23 | } |
@@ -4,12 +4,13 @@ | ||
4 | 4 | using System.Drawing; |
5 | 5 | using System.IO; |
6 | 6 | using nft.framework.plugin; |
7 | - | |
7 | +using System.Diagnostics; | |
8 | +using Encoder = System.Drawing.Imaging.Encoder; | |
8 | 9 | namespace nft.framework.drawing { |
9 | 10 | /// <summary> |
10 | 11 | /// Manage reference count of Image object and dispose on proper timing. |
11 | 12 | /// </summary> |
12 | - public abstract class ImageRef { | |
13 | + public class ImageRef { | |
13 | 14 | /// <summary> |
14 | 15 | /// Used as TranspalentColor to indicate that this image has no color to be transpalent. |
15 | 16 | /// </summary> |
@@ -19,20 +20,28 @@ | ||
19 | 20 | private short refcount; |
20 | 21 | private object imgref = null; |
21 | 22 | private Color transpalent = Color.Magenta; |
23 | + protected IFileSource source; | |
22 | 24 | |
23 | - protected ImageRef() | |
24 | - : this(Lifetime.Long) { | |
25 | + protected ImageRef(IFileSource src) | |
26 | + : this(src, Lifetime.Long) { | |
25 | 27 | } |
26 | 28 | |
27 | - protected ImageRef(Lifetime lifetime) { | |
29 | + protected ImageRef(IFileSource src, Lifetime lifetime) { | |
30 | + this.source = src; | |
28 | 31 | this.life = lifetime; |
29 | 32 | this.refcount = 0; |
30 | 33 | } |
31 | 34 | |
35 | + public IFileSource FileSource { | |
36 | + get { | |
37 | + return source; | |
38 | + } | |
39 | + } | |
40 | + | |
32 | 41 | /// <summary> |
33 | 42 | /// Do not call while reference count is not zero. |
34 | 43 | /// </summary> |
35 | - protected void ForceDispose(){ | |
44 | + protected virtual void ForceDispose(){ | |
36 | 45 | if (refcount > 0) |
37 | 46 | throw new InvalidOperationException("Reference count is not zero."); |
38 | 47 | if (imgref != null) { |
@@ -48,7 +57,7 @@ | ||
48 | 57 | } |
49 | 58 | } |
50 | 59 | |
51 | - protected Image PrepareImage() { | |
60 | + protected virtual Image PrepareImage() { | |
52 | 61 | Image ret; |
53 | 62 | if (imgref != null) { |
54 | 63 | if (imgref is WeakReference) { |
@@ -99,6 +108,20 @@ | ||
99 | 108 | } |
100 | 109 | } |
101 | 110 | |
111 | + protected virtual Image CreateImage() { | |
112 | + //return Image.FromFile(((LocalFile)source).AbsolutePath); | |
113 | + Stream s = source.OpenRead(); | |
114 | + Encoder enc = Encoder.Version; | |
115 | + Image img = Bitmap.FromStream(s); | |
116 | + s.Close(); | |
117 | + s.Dispose(); | |
118 | + return new Bitmap(img); | |
119 | + } | |
120 | + | |
121 | + protected virtual void DisposeImage(Image image) { | |
122 | + image.Dispose(); | |
123 | + } | |
124 | + | |
102 | 125 | /// <summary> |
103 | 126 | /// Decrease reference count. |
104 | 127 | /// Do not Dispose the image which returned by AddRef method. |
@@ -134,11 +157,56 @@ | ||
134 | 157 | set { this.life = value; } |
135 | 158 | } |
136 | 159 | |
137 | - protected virtual void DisposeImage(Image image) { | |
138 | - image.Dispose(); | |
160 | + public override bool Equals(object obj) { | |
161 | + ImageRef iref = obj as ImageRef; | |
162 | + if (iref != null) { | |
163 | + return source.Equals(iref.source); | |
164 | + } else { | |
165 | + return false; | |
166 | + } | |
139 | 167 | } |
140 | 168 | |
141 | - protected abstract Image CreateImage(); | |
169 | + public override int GetHashCode() { | |
170 | + return source.GetHashCode(); | |
171 | + } | |
172 | + | |
173 | + #region local non bundled image treatment. | |
174 | + static private readonly Dictionary<String, ImageRef> pathlist = new Dictionary<String, ImageRef>(); | |
175 | + | |
176 | + /// <summary> | |
177 | + /// Get or create ImageRef object for an image specifed by the file path | |
178 | + /// Caller do not need to call first 'IncreaseRefCount' | |
179 | + /// </summary> | |
180 | + /// <param name="filename"></param> | |
181 | + /// <returns></returns> | |
182 | + public static ImageRef FromFile(string filename) { | |
183 | + string path = Path.GetFullPath(filename); | |
184 | + ImageRef refObj = null; | |
185 | + if (!pathlist.TryGetValue(path, out refObj)) { | |
186 | + FileInfo info = new FileInfo(path); | |
187 | + if (info.Exists) { | |
188 | + IFileSource src = new LocalFile(info.FullName); | |
189 | + refObj = new ImageRef(src); | |
190 | + pathlist.Add(path, refObj); | |
191 | + } | |
192 | + } | |
193 | + return refObj; | |
194 | + } | |
195 | + | |
196 | + public static void FreeIsolatedImages() { | |
197 | + List<string> work = new List<string>(); | |
198 | + foreach (string key in pathlist.Keys) { | |
199 | + ImageRef ir = pathlist[key]; | |
200 | + if (ir.RefCount == 0) { | |
201 | + ir.ForceDispose(); | |
202 | + work.Add(key); | |
203 | + } | |
204 | + } | |
205 | + foreach (string key in work) { | |
206 | + pathlist.Remove(key); | |
207 | + } | |
208 | + } | |
209 | + #endregion | |
142 | 210 | } |
143 | 211 | |
144 | 212 | } |
@@ -6,12 +6,11 @@ | ||
6 | 6 | using System.Runtime.Serialization; |
7 | 7 | using System.Drawing; |
8 | 8 | using System.Diagnostics; |
9 | -using nft.framework.util; | |
10 | 9 | |
11 | 10 | namespace nft.framework.plugin { |
12 | 11 | class PluginImageManager { |
13 | - static private readonly Dictionary<String, ContributionImageRef> pathlist | |
14 | - = new Dictionary<String, ContributionImageRef>(); | |
12 | + static private readonly Dictionary<String, ImageEntry> pathlist | |
13 | + = new Dictionary<String, ImageEntry>(); | |
15 | 14 | |
16 | 15 | /// <summary> |
17 | 16 | /// load image from the plugin directory. |
@@ -21,12 +20,12 @@ | ||
21 | 20 | /// <returns></returns> |
22 | 21 | public static ImageRef GetBundledImageRef(Contribution ctb, string relativePath) { |
23 | 22 | string key = MakePluginPath(ctb, relativePath); |
24 | - ContributionImageRef ir; | |
23 | + ImageEntry ir; | |
25 | 24 | if (!pathlist.TryGetValue(key, out ir)) { |
26 | - ir = new ContributionImageRef(ctb, relativePath, false); | |
25 | + ir = new ImageEntry(ctb, relativePath, false); | |
27 | 26 | pathlist.Add(key, ir); |
28 | 27 | } |
29 | - return ir; | |
28 | + return ImageRef.FromFile(ir.FullPath); | |
30 | 29 | } |
31 | 30 | |
32 | 31 | /// <summary> |
@@ -38,27 +37,14 @@ | ||
38 | 37 | /// <returns></returns> |
39 | 38 | public static ImageRef GetCachedImageRef(Contribution ctb, string relativePath) { |
40 | 39 | string key = MakeCtbCachePath(ctb, relativePath); |
41 | - ContributionImageRef ir; | |
40 | + ImageEntry ir; | |
42 | 41 | if (!pathlist.TryGetValue(key, out ir)) { |
43 | - ir = new ContributionImageRef(ctb, relativePath, true); | |
42 | + ir = new ImageEntry(ctb, relativePath, true); | |
44 | 43 | pathlist.Add(key, ir); |
45 | 44 | } |
46 | - return ir; | |
45 | + return ImageRef.FromFile(ir.FullPath); | |
47 | 46 | } |
48 | 47 | |
49 | - public static void FreeIsolatedImages() { | |
50 | - List<string> work = new List<string>(); | |
51 | - foreach (string key in pathlist.Keys) { | |
52 | - ContributionImageRef ir = pathlist[key]; | |
53 | - if (ir.FreeIsIsolated()) { | |
54 | - work.Add(key); | |
55 | - } | |
56 | - } | |
57 | - foreach (string key in work) { | |
58 | - pathlist.Remove(key); | |
59 | - } | |
60 | - } | |
61 | - | |
62 | 48 | protected internal static string MakePluginPath(Contribution ctb, string relative) { |
63 | 49 | return Path.Combine(ctb.PluginDir, relative); |
64 | 50 | } |
@@ -68,7 +54,7 @@ | ||
68 | 54 | } |
69 | 55 | } |
70 | 56 | |
71 | - class ContributionImageRef : FileImageRef, ISerializable { | |
57 | + class ImageEntry : ISerializable { | |
72 | 58 | protected readonly string cid; |
73 | 59 | protected readonly string relPath; |
74 | 60 | protected readonly string parentDir; |
@@ -81,13 +67,13 @@ | ||
81 | 67 | } |
82 | 68 | } |
83 | 69 | |
84 | - internal ContributionImageRef(Contribution ctb, string relativepath, bool cached) { | |
70 | + internal ImageEntry(Contribution ctb, string relativepath, bool cached) { | |
85 | 71 | this.cid = ctb.ID; |
86 | 72 | this.relPath = relativepath; |
87 | 73 | this.parentDir = ResolveParentDir(ctb, cached); |
88 | 74 | } |
89 | 75 | |
90 | - private ContributionImageRef(SerializationInfo info, StreamingContext context) { | |
76 | + private ImageEntry(SerializationInfo info, StreamingContext context) { | |
91 | 77 | this.cid = info.GetString("cid"); |
92 | 78 | this.relPath = info.GetString("path"); |
93 | 79 | Contribution ctb = PluginManager.theInstance.GetContribution(cid); |
@@ -95,18 +81,10 @@ | ||
95 | 81 | this.parentDir = ResolveParentDir(ctb, cached); |
96 | 82 | } |
97 | 83 | |
98 | - public override string FullPath { | |
84 | + internal protected string FullPath { | |
99 | 85 | get { return Path.Combine(parentDir, relPath); } |
100 | 86 | } |
101 | 87 | |
102 | - internal bool FreeIsIsolated() { | |
103 | - bool b = (RefCount > 0); | |
104 | - if (!b) { | |
105 | - base.ForceDispose(); | |
106 | - } | |
107 | - return b; | |
108 | - } | |
109 | - | |
110 | 88 | #region ISerializable メンバ |
111 | 89 | |
112 | 90 | public void GetObjectData(SerializationInfo info, StreamingContext context) { |
@@ -119,5 +97,6 @@ | ||
119 | 97 | } |
120 | 98 | |
121 | 99 | #endregion |
100 | + | |
122 | 101 | } |
123 | 102 | } |
@@ -0,0 +1,119 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using System.IO; | |
5 | + | |
6 | +using AccessSpeed = nft.framework.FileAccessSpeed; | |
7 | + | |
8 | +namespace nft.framework | |
9 | +{ | |
10 | + public enum FileAccessSpeed | |
11 | + { | |
12 | + Fast, // Ordinaly local file (stored as is). | |
13 | + Slow, // Compressed local file (ZIP), , or Stored in a bit slow device. | |
14 | + VerySlow // Network remote file, or sometimes failed to open and require reload. | |
15 | + } | |
16 | + | |
17 | + public interface IFileSource | |
18 | + { | |
19 | + /// <summary> | |
20 | + /// Open File as Stream | |
21 | + /// </summary> | |
22 | + /// <returns></returns> | |
23 | + Stream OpenRead(); | |
24 | + | |
25 | + AccessSpeed AccessSpeed { get; } | |
26 | + | |
27 | + /// <summary> | |
28 | + /// File offset path. Must be identical and consist of | |
29 | + /// characters available for offset path, in oredr to create cache. | |
30 | + /// </summary> | |
31 | + string IdenticalPath { get; } | |
32 | + | |
33 | + /// <summary> | |
34 | + /// Reffered when cache is latest or not. Negative value will force update cache. | |
35 | + /// </summary> | |
36 | + long Timestamp { get; } | |
37 | + } | |
38 | + | |
39 | + public abstract class FileSource : IFileSource | |
40 | + { | |
41 | + public abstract string IdenticalPath { get; } | |
42 | + | |
43 | + public abstract Stream OpenRead(); | |
44 | + | |
45 | + public override bool Equals(object obj) { | |
46 | + IFileSource iref = obj as IFileSource; | |
47 | + if (iref != null) { | |
48 | + return IdenticalPath.Equals(iref.IdenticalPath); | |
49 | + } else { | |
50 | + return false; | |
51 | + } | |
52 | + } | |
53 | + | |
54 | + public override int GetHashCode() { | |
55 | + return IdenticalPath.GetHashCode(); | |
56 | + } | |
57 | + | |
58 | + [Obsolete("non blocking method is desired.")] | |
59 | + public virtual void CopyToLocal(string path) { | |
60 | + using (Stream s_in = OpenRead()) { | |
61 | + using (FileStream s_out = new FileStream(path, FileMode.Create, FileAccess.Write)) { | |
62 | + int size = 4096; | |
63 | + byte[] buffer = new byte[size]; | |
64 | + int numBytes; | |
65 | + while ((numBytes = s_in.Read(buffer, 0, size)) > 0) { | |
66 | + s_out.Write(buffer, 0, numBytes); | |
67 | + } | |
68 | + } | |
69 | + } | |
70 | + } | |
71 | + | |
72 | + public abstract AccessSpeed AccessSpeed { get; } | |
73 | + | |
74 | + public abstract long Timestamp { get; } | |
75 | + } | |
76 | + | |
77 | + public class LocalFile : FileSource, IFileSource | |
78 | + { | |
79 | + protected string idpath; | |
80 | + protected string fullpath; | |
81 | + public LocalFile(string path) { | |
82 | + this.fullpath = Path.GetFullPath(path); | |
83 | + this.idpath = this.fullpath.Replace(":\\", "$\\"); | |
84 | + } | |
85 | + | |
86 | + public LocalFile(string parent_path, string offset_path) { | |
87 | + Char c = offset_path[0]; | |
88 | + if (c == '/' || c == '\\') { | |
89 | + this.idpath = offset_path.Substring(1); | |
90 | + } else { | |
91 | + this.idpath = offset_path; | |
92 | + } | |
93 | + this.fullpath = Path.Combine(parent_path, this.idpath); | |
94 | + } | |
95 | + | |
96 | + public override Stream OpenRead() { | |
97 | + return new FileStream(fullpath, FileMode.Open, FileAccess.Read); | |
98 | + } | |
99 | + | |
100 | + public override AccessSpeed AccessSpeed { | |
101 | + get { return AccessSpeed.Fast; } | |
102 | + } | |
103 | + | |
104 | + public override string IdenticalPath { | |
105 | + get { return idpath; } | |
106 | + } | |
107 | + | |
108 | + public string AbsolutePath { | |
109 | + get { return fullpath; } | |
110 | + } | |
111 | + | |
112 | + public override long Timestamp { | |
113 | + get { | |
114 | + FileInfo info =new FileInfo(AbsolutePath); | |
115 | + return info.LastAccessTime.Ticks; | |
116 | + } | |
117 | + } | |
118 | + } | |
119 | +} |
@@ -25,7 +25,7 @@ | ||
25 | 25 | |
26 | 26 | public IEnumerator<KeyValuePair<String, IParamsParser>> EnumChildren() { |
27 | 27 | foreach (XmlAttribute a in node.Attributes) { |
28 | - yield return new KeyValuePair<String,IParamsParser>(a.Name, new PlainStringParam(a.Value)); | |
28 | + yield return new KeyValuePair<String,IParamsParser>(a.Name, new PlainStringParam(a.Value, this)); | |
29 | 29 | } |
30 | 30 | foreach (XmlNode n in node.ChildNodes) { |
31 | 31 | yield return new KeyValuePair<String, IParamsParser>(n.Name, new XmlParamParser(n)); |
@@ -36,7 +36,7 @@ | ||
36 | 36 | if (node.Attributes != null) { |
37 | 37 | XmlAttribute a = node.Attributes[key]; |
38 | 38 | if (a != null) { |
39 | - yield return new PlainStringParam(a.Value); | |
39 | + yield return new PlainStringParam(a.Value, this); | |
40 | 40 | } |
41 | 41 | } |
42 | 42 | foreach (XmlNode n in node.SelectNodes(key)) { |
@@ -43,6 +43,15 @@ | ||
43 | 43 | yield return new XmlParamParser(n); |
44 | 44 | } |
45 | 45 | } |
46 | + | |
47 | + public IFileSource GetFileSource(string path) { | |
48 | + Uri uri= XmlUtil.resolve(node, path); | |
49 | + if (uri.IsFile) { | |
50 | + return new LocalFile(uri.LocalPath); | |
51 | + } else { | |
52 | + return null; | |
53 | + } | |
54 | + } | |
46 | 55 | } |
47 | 56 | |
48 | 57 | } |
@@ -17,9 +17,26 @@ | ||
17 | 17 | /// </summary> |
18 | 18 | bool IsNull { get; } |
19 | 19 | |
20 | + /// <summary> | |
21 | + /// Enumelate all children with it's key. | |
22 | + /// </summary> | |
23 | + /// <returns></returns> | |
20 | 24 | IEnumerator<KeyValuePair<String,IParamsParser>> EnumChildren(); |
21 | 25 | |
26 | + /// <summary> | |
27 | + /// Enumelate all children which corresnpond to specified key. | |
28 | + /// </summary> | |
29 | + /// <param name="key"></param> | |
30 | + /// <returns></returns> | |
22 | 31 | IEnumerator<IParamsParser> EnumChildren(string key); |
32 | + | |
33 | + /// <summary> | |
34 | + /// Resolve offset file path and returns as IFileSource. | |
35 | + /// returns null if corresponding file does not found. | |
36 | + /// </summary> | |
37 | + /// <param name="path"></param> | |
38 | + /// <returns></returns> | |
39 | + IFileSource GetFileSource(string path); | |
23 | 40 | } |
24 | 41 | |
25 | 42 | public sealed class NullParam : IParamsParser { |
@@ -42,15 +59,24 @@ | ||
42 | 59 | public IEnumerator<IParamsParser> EnumChildren(string key) { |
43 | 60 | yield break; |
44 | 61 | } |
62 | + | |
63 | + public IFileSource GetFileSource(string path) { | |
64 | + return null; | |
65 | + } | |
45 | 66 | } |
46 | 67 | |
47 | 68 | public class PlainStringParam : IParamsParser |
48 | 69 | { |
49 | 70 | private readonly string text; |
50 | - public PlainStringParam(string s) { | |
71 | + private readonly IParamsParser owner; | |
72 | + public PlainStringParam(string s, IParamsParser owner) { | |
51 | 73 | this.text = s; |
74 | + this.owner = owner; | |
52 | 75 | } |
53 | 76 | |
77 | + public PlainStringParam(string s) :this(s, null){ | |
78 | + } | |
79 | + | |
54 | 80 | public string InnerText { |
55 | 81 | get { return text; } |
56 | 82 | } |
@@ -66,5 +92,13 @@ | ||
66 | 92 | public IEnumerator<IParamsParser> EnumChildren(string key) { |
67 | 93 | yield break; |
68 | 94 | } |
95 | + | |
96 | + public IFileSource GetFileSource(string path) { | |
97 | + if (owner != null) { | |
98 | + return owner.GetFileSource(path); | |
99 | + } else { | |
100 | + return null; | |
101 | + } | |
102 | + } | |
69 | 103 | } |
70 | 104 | } |
@@ -37,6 +37,15 @@ | ||
37 | 37 | } |
38 | 38 | } |
39 | 39 | |
40 | + public IFileSource GetFileSource(string path) { | |
41 | + IFileSource src = null; | |
42 | + foreach (IParamsParser pp in loader) { | |
43 | + src = pp.GetFileSource(path); | |
44 | + if (src != null) break; | |
45 | + } | |
46 | + return src; | |
47 | + } | |
48 | + | |
40 | 49 | public ParamsReader this[int index] { |
41 | 50 | get { |
42 | 51 | if (index < 0 || index >= loader.Length) { |
@@ -1,27 +0,0 @@ | ||
1 | -using System; | |
2 | -using System.Collections.Generic; | |
3 | -using System.Text; | |
4 | -using nft.framework.drawing; | |
5 | -using System.IO; | |
6 | -using System.Drawing; | |
7 | -using System.Runtime.Serialization; | |
8 | - | |
9 | -namespace nft.framework.util { | |
10 | - public abstract class FileImageRef : ImageRef { | |
11 | - | |
12 | - public abstract string FullPath { get; } | |
13 | - | |
14 | - protected override Image CreateImage() { | |
15 | - return Image.FromFile(FullPath); | |
16 | - } | |
17 | - | |
18 | - public override bool Equals(object obj) { | |
19 | - FileImageRef iref = obj as FileImageRef; | |
20 | - return FullPath.Equals(iref.FullPath); | |
21 | - } | |
22 | - | |
23 | - public override int GetHashCode() { | |
24 | - return FullPath.GetHashCode(); | |
25 | - } | |
26 | - } | |
27 | -} |
@@ -1,52 +0,0 @@ | ||
1 | -using System; | |
2 | -using System.Collections.Generic; | |
3 | -using System.Text; | |
4 | -using nft.framework.drawing; | |
5 | -using System.IO; | |
6 | -using System.Drawing; | |
7 | -using System.Runtime.Serialization; | |
8 | - | |
9 | -namespace nft.framework.util { | |
10 | - public class LocalFileImageRef : FileImageRef { | |
11 | - static private readonly Dictionary<String, LocalFileImageRef> pathlist | |
12 | - = new Dictionary<String, LocalFileImageRef>(); | |
13 | - | |
14 | - public readonly string path; | |
15 | - | |
16 | - private LocalFileImageRef(string id) { | |
17 | - this.path = id; | |
18 | - } | |
19 | - | |
20 | - public override string FullPath { get { return path; } } | |
21 | - | |
22 | - /// <summary> | |
23 | - /// Get or create ImageRef object for an image specifed by the file path | |
24 | - /// Caller do not need to call first 'IncreaseRefCount' | |
25 | - /// </summary> | |
26 | - /// <param name="filename"></param> | |
27 | - /// <returns></returns> | |
28 | - public static ImageRef FromFile(string filename) { | |
29 | - string path = Path.GetFullPath(filename); | |
30 | - LocalFileImageRef refObj = null; | |
31 | - if (!pathlist.TryGetValue(path, out refObj)) { | |
32 | - refObj = new LocalFileImageRef(path); | |
33 | - pathlist.Add(path, refObj); | |
34 | - } | |
35 | - return refObj; | |
36 | - } | |
37 | - | |
38 | - public static void FreeIsolatedImages() { | |
39 | - List<string> work = new List<string>(); | |
40 | - foreach (string key in pathlist.Keys) { | |
41 | - LocalFileImageRef ir = pathlist[key]; | |
42 | - if (ir.RefCount == 0) { | |
43 | - ir.ForceDispose(); | |
44 | - work.Add(key); | |
45 | - } | |
46 | - } | |
47 | - foreach (string key in work) { | |
48 | - pathlist.Remove(key); | |
49 | - } | |
50 | - } | |
51 | - } | |
52 | -} |
@@ -45,7 +45,7 @@ | ||
45 | 45 | Detach(attached); |
46 | 46 | attached = source; |
47 | 47 | this.attachLevel = attachLevel -1; |
48 | - source.OnProgress += new ProgressHandler(this.AttachListener); | |
48 | + source.OnProgress += new ProgressHandler(this.HandleOnProgress); | |
49 | 49 | } |
50 | 50 | |
51 | 51 | /// <summary> |
@@ -54,7 +54,7 @@ | ||
54 | 54 | /// <param name="source"></param> |
55 | 55 | public void Detach( ProgressMonitor source ) |
56 | 56 | { |
57 | - OnProgress -= new ProgressHandler(this.AttachListener); | |
57 | + OnProgress -= new ProgressHandler(this.HandleOnProgress); | |
58 | 58 | } |
59 | 59 | |
60 | 60 | #region lapper methods |
@@ -96,7 +96,7 @@ | ||
96 | 96 | } |
97 | 97 | |
98 | 98 | // delegate called from attached monitor |
99 | - private void AttachListener( int level, int percentage ,string msg ) | |
99 | + internal protected void HandleOnProgress( int level, int percentage ,string msg ) | |
100 | 100 | { |
101 | 101 | if (OnProgress != null) { |
102 | 102 | OnProgress(attachLevel + level, percentage, msg); |
@@ -151,7 +151,7 @@ | ||
151 | 151 | { |
152 | 152 | max = value; |
153 | 153 | current = 0; |
154 | - owner.OnProgress(level,0,null); | |
154 | + owner.HandleOnProgress(level, 0, null); | |
155 | 155 | } |
156 | 156 | } |
157 | 157 |
@@ -161,7 +161,7 @@ | ||
161 | 161 | set |
162 | 162 | { |
163 | 163 | text = value; |
164 | - owner.OnProgress(level,percentage,text); | |
164 | + owner.HandleOnProgress(level,percentage,text); | |
165 | 165 | } |
166 | 166 | } |
167 | 167 | #endregion |
@@ -176,7 +176,7 @@ | ||
176 | 176 | text = msg; |
177 | 177 | current += count; |
178 | 178 | if(max<current) current = max; |
179 | - owner.OnProgress(level,percentage,text); | |
179 | + owner.HandleOnProgress(level, percentage, text); | |
180 | 180 | } |
181 | 181 | } |
182 | 182 | } |
@@ -3,6 +3,7 @@ | ||
3 | 3 | using System.IO; |
4 | 4 | using System.Net; |
5 | 5 | using System.Xml; |
6 | +using System.Diagnostics; | |
6 | 7 | |
7 | 8 | namespace nft.util |
8 | 9 | { |
@@ -84,7 +85,12 @@ | ||
84 | 85 | /// </summary> |
85 | 86 | public static Uri resolve( XmlNode context, string relative ) |
86 | 87 | { |
87 | - return new Uri(new Uri(context.BaseURI),relative); | |
88 | + Char c = relative[0]; | |
89 | + if(c=='/' || c=='\\'){ | |
90 | + relative = relative.Substring(1); | |
91 | + } | |
92 | + Uri baseuri = new Uri(context.BaseURI); | |
93 | + return new Uri(baseuri,relative); | |
88 | 94 | } |
89 | 95 | |
90 | 96 | /// <summary> |
@@ -12,7 +12,7 @@ | ||
12 | 12 | { |
13 | 13 | class ParamsReaderTest |
14 | 14 | { |
15 | - static readonly string xmlPath = @"\system\plugin.xml"; | |
15 | + static readonly string xmlPath = @"system\plugin.xml"; | |
16 | 16 | static XmlDocument doc; |
17 | 17 | |
18 | 18 | static ParamsReaderTest() { |
@@ -35,6 +35,16 @@ | ||
35 | 35 | Debug.WriteLine("command = " + r4["menupath"].InnerText); |
36 | 36 | } |
37 | 37 | } |
38 | + IFileSource fs = reader.GetFileSource("test.txt"); | |
39 | + Debug.WriteLine("file=" + (fs != null ? fs.IdenticalPath : "null")); | |
40 | + fs = reader.GetFileSource("work/test2.txt"); | |
41 | + Debug.WriteLine("file2=" + (fs != null ? fs.IdenticalPath : "null")); | |
42 | + fs = reader.GetFileSource(@"/work/test3.txt"); | |
43 | + Debug.WriteLine("file3=" + (fs != null ? fs.IdenticalPath : "null")); | |
44 | + fs = reader.GetFileSource(@"work\test4.txt"); | |
45 | + Debug.WriteLine("file4=" + (fs != null ? fs.IdenticalPath : "null")); | |
46 | + fs = reader.GetFileSource(@"\work\test5.txt"); | |
47 | + Debug.WriteLine("file5=" + (fs != null ? fs.IdenticalPath : "null")); | |
38 | 48 | } |
39 | 49 | |
40 | 50 | } |
@@ -112,9 +112,9 @@ | ||
112 | 112 | // |
113 | 113 | // detail |
114 | 114 | // |
115 | - this.detail.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | |
116 | - | System.Windows.Forms.AnchorStyles.Left) | |
117 | - | System.Windows.Forms.AnchorStyles.Right))); | |
115 | + this.detail.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | |
116 | + | System.Windows.Forms.AnchorStyles.Left) | |
117 | + | System.Windows.Forms.AnchorStyles.Right))); | |
118 | 118 | this.detail.Location = new System.Drawing.Point(16, 80); |
119 | 119 | this.detail.Multiline = true; |
120 | 120 | this.detail.Name = "detail"; |
@@ -137,8 +137,8 @@ | ||
137 | 137 | // |
138 | 138 | // msg |
139 | 139 | // |
140 | - this.msg.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | |
141 | - | System.Windows.Forms.AnchorStyles.Right))); | |
140 | + this.msg.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | |
141 | + | System.Windows.Forms.AnchorStyles.Right))); | |
142 | 142 | this.msg.Location = new System.Drawing.Point(72, 8); |
143 | 143 | this.msg.Name = "msg"; |
144 | 144 | this.msg.Size = new System.Drawing.Size(536, 48); |
@@ -155,7 +155,7 @@ | ||
155 | 155 | this.linkLabel1.TabIndex = 4; |
156 | 156 | this.linkLabel1.TabStop = true; |
157 | 157 | this.linkLabel1.TargetUrl = "http://www.kohsuke.org/freetrain/wiki/pukiwiki.php?%A5%D0%A5%B0%CA%F3%B9%F0%A4%CE" + |
158 | - "%BC%EA%BD%E7"; | |
158 | + "%BC%EA%BD%E7"; | |
159 | 159 | this.linkLabel1.Text = " バグの報告先"; |
160 | 160 | this.linkLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; |
161 | 161 | // |
@@ -171,8 +171,8 @@ | ||
171 | 171 | // |
172 | 172 | // note |
173 | 173 | // |
174 | - this.note.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | |
175 | - | System.Windows.Forms.AnchorStyles.Right))); | |
174 | + this.note.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | |
175 | + | System.Windows.Forms.AnchorStyles.Right))); | |
176 | 176 | this.note.BackColor = System.Drawing.SystemColors.Highlight; |
177 | 177 | this.note.ForeColor = System.Drawing.SystemColors.HighlightText; |
178 | 178 | this.note.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; |
@@ -186,7 +186,6 @@ | ||
186 | 186 | // throwButton |
187 | 187 | // |
188 | 188 | this.throwButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); |
189 | - this.throwButton.DialogResult = System.Windows.Forms.DialogResult.Abort; | |
190 | 189 | this.throwButton.Location = new System.Drawing.Point(200, 220); |
191 | 190 | this.throwButton.Name = "throwButton"; |
192 | 191 | this.throwButton.Size = new System.Drawing.Size(146, 23); |
@@ -193,6 +192,7 @@ | ||
193 | 192 | this.throwButton.TabIndex = 7; |
194 | 193 | this.throwButton.Text = "再throw(開発用)"; |
195 | 194 | this.throwButton.UseVisualStyleBackColor = true; |
195 | + this.throwButton.Click += new System.EventHandler(this.throwButton_Click); | |
196 | 196 | // |
197 | 197 | // ErrorMessageBox |
198 | 198 | // |
@@ -222,5 +222,9 @@ | ||
222 | 222 | string text = detail.Text;//.Replace("\n","\r\n"); |
223 | 223 | Clipboard.SetDataObject(text, true); |
224 | 224 | } |
225 | + | |
226 | + private void throwButton_Click(object sender, EventArgs e) { | |
227 | + throw exception; | |
228 | + } | |
225 | 229 | } |
226 | 230 | } |
@@ -14,7 +14,6 @@ | ||
14 | 14 | using System.Collections; |
15 | 15 | using System.Runtime.InteropServices; |
16 | 16 | using nft.framework.drawing; |
17 | -using nft.framework.util; | |
18 | 17 | |
19 | 18 | using Generator = nft.contributions.game.CtbImageImportTerrainGenerator; |
20 | 19 | namespace nft.ui.core { |
@@ -109,7 +108,7 @@ | ||
109 | 108 | ClearSelectedImage(); |
110 | 109 | ImageRef img = null; |
111 | 110 | try { |
112 | - img = LocalFileImageRef.FromFile(path); | |
111 | + img = ImageRef.FromFile(path); | |
113 | 112 | } catch (Exception) { |
114 | 113 | MessageBox.Show( |
115 | 114 | this, "ファイルを画像として開けません\n" + path, "読み込み画像", MessageBoxButtons.OK |