view codegear/InputDataGear.cs @ 51:486683ead53f

bug survey
author riono <e165729@ie.u-ryukyu.ac.jp>
date Tue, 11 Jan 2022 20:02:18 +0900
parents 96fc5e71274e
children
line wrap: on
line source

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

namespace Christie_net.codegear {
// InputDataGearの待ち合わせの管理
public class InputDataGear {
    public ConcurrentDictionary<string, DataGear<object>> inputValue = new ConcurrentDictionary<string, DataGear<object>>();
    public CodeGearManager cgm;
    public CodeGear cg;
    private int count = 0;
    private readonly object syncObject = new object();
    

    public InputDataGear(CodeGear cg) {
        this.cg = cg;
    }

    public void FinishInput(CodeGearManager cgm, List<Command> commandList) {
        this.cgm = cgm;
        Interlocked.Add(ref count, commandList.Count);

        if (count == 0) {
            SubmitCG();
        }

        foreach (Command cm in commandList) {
            cgm.GetDGM(cm.toDgmName).RunCommand(cm);
        }
    }

    public void SetInputs(string key, DataGear<object> dg) {
        inputValue.TryAdd(key, dg);
        Decriment();
    }

    // commandが実行されるたびにDecrementする
    private void Decriment() {
        lock (syncObject) {
            Interlocked.Decrement(ref count);
            if (count == 0) {
                SetInputValue();
                SubmitCG();
            }
        }
    }
    
    private void SubmitCG() {
        cgm.Submit(cg);
    }

    public void SetInputValue() {
        foreach (var field in cg.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic |
                                                       BindingFlags.DeclaredOnly | BindingFlags.Instance)) {
            if (Attribute.IsDefined(field, typeof(Take)) || Attribute.IsDefined(field, typeof(TakeFrom)) ||
                Attribute.IsDefined(field, typeof(Peek)) || Attribute.IsDefined(field, typeof(PeekFrom))) {
                try {
                    field.SetValue(cg, TypeCheck(field.Name));
                } catch { }
            }
        }
    }

    public Object TypeCheck(string key) {
        if (inputValue[key].GetData() != null) {
            return inputValue[key].GetData();
        } else {
            throw new ArgumentException("'" + key + "' is null! this DataGear required type of " +
                                        inputValue[key].GetClazz());
        }
    }
}
}