using UnityEngine; using System.IO; using System.Collections.Generic; using System; using System.Threading; using System.Collections; using UnityEngine.Events; public class ImageFileWatcher : MonoBehaviour { //public string originFolder; public static ImageFileWatcher instance; [Serializable] public class TextureDataHandler : UnityEvent { }; public TextureDataHandler TextureAddedEvent = new TextureDataHandler(); public TextureDataHandler TextureRemovedEvent = new TextureDataHandler(); public int photoSize = 0; public float photoCheckingPeriod = 0.2f; public int maxNum = 20; [Tooltip("the root path is unity project path")] public string rootPath = "Scan"; public Texture2D[] texListForDebugging; public bool clearAfterLoaded = false; private string todayFolder = DateTime.Now.ToString("yyyy-MM-dd"); private Queue waiting_queue = new Queue(); private Queue ready_queue = new Queue(); private Queue texturePool = new Queue(); private Thread loadingThread; private bool isThreadRunning = true; private FileSystemWatcher watcher; public Dictionary type_map = new Dictionary(); [SerializeField] private bool search_last_file = false; [SerializeField] private bool dailyFolder = true; [SerializeField] private bool isRelative = false; void Awake() { instance = this; //rootPath = Application.dataPath + "/"+rootPath; } void Start() { DateTime date = DateTime.Now; if (isRelative) rootPath = Application.dataPath + "\\" + rootPath; if (search_last_file) { List historic_files = find_last_files(); foreach (string file in historic_files) { lock (waiting_queue) { waiting_queue.Enqueue(new TextureData(file)); } } } //string[] dir_list = {"2013.02.21","2010.06.20","1985.08.27","3820.01.02" }; if (!Directory.Exists(rootPath)) { Directory.CreateDirectory(rootPath); } string watch_path = rootPath; if (dailyFolder) { watch_path = rootPath + "/" + todayFolder; if (!Directory.Exists(watch_path)) { Directory.CreateDirectory(watch_path); } } watcher = new FileSystemWatcher(watch_path); watcher.Created += onFileChanged; watcher.EnableRaisingEvents = true; loadingThread = new Thread(new ThreadStart(resizing_to_memory_service)); loadingThread.Start(); StartCoroutine(loadTextureFromMemory()); /* TextureAddedEvent += (TextureData t) => { //Debug.Log("Add " + t); }; TextureRemovedEvent += (TextureData t) => { //Debug.Log("Remove " + t); };*/ } void OnDestroy() { isThreadRunning = false; while (loadingThread.IsAlive) { Thread.Sleep(1); } loadingThread.Abort(); } IEnumerator loadTextureFromMemory() { while (true) { if (ready_queue.Count > 0) { TextureData newData = null; lock (ready_queue) { newData = ready_queue.Dequeue(); } if(newData.createTextureFromMemory()) { yield return null; texturePool.Enqueue(newData); TextureAddedEvent.Invoke(newData); if (clearAfterLoaded) { File.Delete(newData.filePath); } yield return null; while (texturePool.Count > maxNum) { TextureData removalData = texturePool.Dequeue(); TextureRemovedEvent.Invoke(removalData); removalData.destroyTexture(); } texListForDebugging = new Texture2D[texturePool.Count]; int i = 0; foreach(TextureData data in texturePool) { texListForDebugging[i++] = data.texture; } } } yield return new WaitForSeconds(photoCheckingPeriod); } } private List find_last_files() { List result = new List(); string[] dir_list = Directory.GetDirectories(rootPath); Array.Sort(dir_list); bool ok = false; for (int i = dir_list.Length - 1; i >= 0; --i) { var png_files = Directory.GetFiles(dir_list[i], "*.png"); var jpg_files = Directory.GetFiles(dir_list[i], "*.jpg"); var files_list = new List(); files_list.AddRange(png_files); files_list.AddRange(jpg_files); string[] file_list = files_list.ToArray(); //string[] file_list = Directory.GetFiles(dir_list[i], "*.png"); Array.Sort(file_list); for (int j = file_list.Length - 1; j >= 0; --j) { result.Add(file_list[j]); if (ok = (result.Count >= maxNum)) break; } if (ok) break; } result.Reverse(); return result; } private void onFileChanged(object sender, FileSystemEventArgs e) { TextureData data = new TextureData(e.FullPath); lock (waiting_queue) { waiting_queue.Enqueue(data); } Debug.Log("onFileChanged() "+ e.FullPath); } private void resizing_to_memory_service() { while (isThreadRunning) { if (waiting_queue.Count > 0) { TextureData data = null; lock (waiting_queue) { data = waiting_queue.Dequeue(); } string str = data.ToString(); if (data.loadToMemory(photoSize)) { lock (ready_queue) { ready_queue.Enqueue(data); } str = "[ OK ]" + str; } else { str = "[FAIL]" + str; } Debug.Log(str); } else { Thread.Sleep((int)(photoCheckingPeriod * 1000)); } } } }