You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
6.8 KiB

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<TextureData> { };
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<TextureData> waiting_queue = new Queue<TextureData>();
private Queue<TextureData> ready_queue = new Queue<TextureData>();
private Queue<TextureData> texturePool = new Queue<TextureData>();
private Thread loadingThread;
private bool isThreadRunning = true;
private FileSystemWatcher watcher;
public Dictionary<string, GameObject> type_map = new Dictionary<string, GameObject>();
[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<string> 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<string> find_last_files()
{
List<string> result = new List<string>();
string[] dir_list = Directory.GetDirectories(rootPath);
Array.Sort<string>(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<string>();
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<string>(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));
}
}
}
}