view datagear/DataGears.cs @ 17:4a3115ba746d

fix CommandType enum
author riono <e165729@ie.u-ryukyu.ac.jp>
date Tue, 24 Nov 2020 03:11:50 +0900
parents 49521c7269bc
children c9d1a5a79254
line wrap: on
line source

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Christie_net.annotation;
using Christie_net.datagear.command;
using Christie_net.datagear.dg;

namespace Christie_net.datagear {
public class DataGears {
    protected SortedDictionary<string, ConcurrentQueue<DataGear<object>>> dataGears =
        new SortedDictionary<string, ConcurrentQueue<DataGear<object>>>();

    private readonly object syncObject = new object();

    /// <summary>
    /// 新しいdataGearの追加
    /// </summary>
    /// <param name="key"></param>
    /// <param name="dg"></param>
    public void Put(string key, DataGear<object> dg) {
        lock (syncObject) {
            if (dataGears.ContainsKey(key)) {
                dataGears[key].Enqueue(dg);
            } else {
                var queue = new ConcurrentQueue<DataGear<object>>();
                queue.Enqueue(dg);
                dataGears.Add(key, queue);
            }
        }
    }

    /// <summary>
    /// DataGeraの取得と削除
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public object Take(string key) {
        object data = null;
        // Queueからの取得は参照渡し
        DataGear<object> dataGear;
        if (dataGears[key].TryDequeue(out dataGear)) {
            data = dataGear.GetData();
        }
        
        // DataGeraを削除取り出ししたのでkeyも削除
        if (dataGears[key].IsEmpty) {
            dataGears.Remove(key);
        }

        return data;
    }

    /// <summary>
    /// DataGeraを削除せずに取得
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public object Peek(string key) {
        object data = null;
        DataGear<object> dataGear;
        if (dataGears[key].TryPeek(out dataGear)) {
            data = dataGear.GetData();
        }

        return data;
    }

    /// <summary>
    /// commandによりDataの取得
    /// </summary>
    /// <param name="cm"></param>
    /// <returns></returns>
    public object GetData(Command cm) {
        lock (syncObject) {
            CommandType type = cm.type;
            if (type == CommandType.TAKE || type == CommandType.REMOTETAKE) {
                return Take(cm.key);
            } else if (type == CommandType.PEEK || type == CommandType.REMOTEPEEK){
                return Peek(cm.key);
            }
            return null;
        }
    }

    /// <summary>
    /// Dataを挿入する
    /// </summary>
    /// <param name="cm"></param>
    public void SetData(Command cm) {
        lock (syncObject) {
            Put(cm.key, cm.dg);
        }
    }

    /// <summary>
    /// 既にkeyが含まれているか返す
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public bool ContainsKey(string key) {
        lock (syncObject) {
            return dataGears.ContainsKey(key);
        }
    }
}
}