<commit_before>﻿using DFHack;
using RemoteFortressReader;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemManager : MonoBehaviour
{
    public static ItemManager Instance { get; private set; }

    static Dictionary<MatPairStruct, ItemModel> itemPrefabs = new Dictionary<MatPairStruct, ItemModel>();

    public ItemModel defaultItem;

    IEnumerator LoadItems()
    {
        if (DFConnection.Instance.NetItemList == null)
            yield break;
        var stopWatch = System.Diagnostics.Stopwatch.StartNew();
        var itemList = DFConnection.Instance.NetItemList.material_list;

        foreach (var item in itemList)
        {
            string path = "Items/" + item.id;
            var loadedItem = Resources.Load<ItemModel>(path);
            if(loadedItem == null)
            {
                //Debug.LogWarning("Cannot find model for " + item.id);
                if (stopWatch.ElapsedMilliseconds > 100)
                {
                    yield return null;
                    stopWatch.Reset();
                    stopWatch.Start();
                }
                continue;
            }

            itemPrefabs[item.mat_pair] = loadedItem;
            if (stopWatch.ElapsedMilliseconds > 100)
            {
                yield return null;
                stopWatch.Reset();
                stopWatch.Start();
            }
        }
    }

    private void Awake()
    {
        Instance = this;
    }

    private void Start()
    {
        ContentLoader.RegisterLoadCallback(LoadItems);
    }

    private void LateUpdate()
    {
        UpdateVisibility();
    }

    Dictionary<int, ItemModel> sceneItems = new Dictionary<int, ItemModel>();
    Dictionary<DFCoord, int> itemCount = new Dictionary<DFCoord, int>();
    HashSet<int> removedItems = new HashSet<int>();
    bool loadedAnyItems = false;
    private Coroutine updateRoutine;

    internal void BeginExistenceCheck()
    {
        removedItems.Clear();
        removedItems.UnionWith(sceneItems.Keys);
        itemCount.Clear();
    }

    internal void EndExitenceCheck()
    {
        if (!loadedAnyItems)
            return;
        if (updateRoutine != null)
            StopCoroutine(updateRoutine);
        foreach (var index in removedItems)
        {
            Destroy(sceneItems[index].gameObject);
            sceneItems.Remove(index);
            itemCache.Remove(index);
        }
        loadedAnyItems = false;
        updateRoutine = StartCoroutine(CreateAllItems());
    }

    Dictionary<int, Item> itemCache = new Dictionary<int, Item>();

    internal void LoadBlock(MapBlock block)
    {
        if (block.items.Count > 0)
            loadedAnyItems = true;
        foreach (var item in block.items)
        {
            removedItems.Remove(item.id);

            itemCache[item.id] = item;
        }
    }

    IEnumerator CreateAllItems()
    {
        var stopWatch = System.Diagnostics.Stopwatch.StartNew();
        foreach (var item in itemCache)
        {
            UpdateItem(item.Value);
            if (stopWatch.ElapsedMilliseconds > 100)
            {
                yield return null;
                stopWatch.Reset();
                stopWatch.Start();
            }
        }
        updateRoutine = null;
    }

    void UpdateItem(Item item)
    {
        ItemModel placedItem;
        if (!sceneItems.ContainsKey(item.id))
        {
            if (itemCount.ContainsKey(item.pos) && itemCount[item.pos] >= GameSettings.Instance.rendering.maxItemsPerTile)
                return;

            placedItem = InstantiateItem(item, transform);
            sceneItems[item.id] = placedItem;
        }
        else
            placedItem = sceneItems[item.id];

        if (itemCount.ContainsKey(item.pos) && itemCount[item.pos] >= GameSettings.Instance.rendering.maxItemsPerTile)
        {
            placedItem.gameObject.SetActive(false);
            return;
        }
        int currentTileCount = 0;
        if (itemCount.ContainsKey(item.pos))
            currentTileCount = itemCount[item.pos];<commit_msg>Change item update timeout to 20ms, from 100<commit_after>﻿using DFHack;
using RemoteFortressReader;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemManager : MonoBehaviour
{
    public static ItemManager Instance { get; private set; }

    static Dictionary<MatPairStruct, ItemModel> itemPrefabs = new Dictionary<MatPairStruct, ItemModel>();

    public ItemModel defaultItem;

    IEnumerator LoadItems()
    {
        if (DFConnection.Instance.NetItemList == null)
            yield break;
        var stopWatch = System.Diagnostics.Stopwatch.StartNew();
        var itemList = DFConnection.Instance.NetItemList.material_list;

        foreach (var item in itemList)
        {
            string path = "Items/" + item.id;
            var loadedItem = Resources.Load<ItemModel>(path);
            if(loadedItem == null)
            {
                //Debug.LogWarning("Cannot find model for " + item.id);
                if (stopWatch.ElapsedMilliseconds > 100)
                {
                    yield return null;
                    stopWatch.Reset();
                    stopWatch.Start();
                }
                continue;
            }

            itemPrefabs[item.mat_pair] = loadedItem;
            if (stopWatch.ElapsedMilliseconds > 100)
            {
                yield return null;
                stopWatch.Reset();
                stopWatch.Start();
            }
        }
    }

    private void Awake()
    {
        Instance = this;
    }

    private void Start()
    {
        ContentLoader.RegisterLoadCallback(LoadItems);
    }

    private void LateUpdate()
    {
        UpdateVisibility();
    }

    Dictionary<int, ItemModel> sceneItems = new Dictionary<int, ItemModel>();
    Dictionary<DFCoord, int> itemCount = new Dictionary<DFCoord, int>();
    HashSet<int> removedItems = new HashSet<int>();
    bool loadedAnyItems = false;
    private Coroutine updateRoutine;

    internal void BeginExistenceCheck()
    {
        removedItems.Clear();
        removedItems.UnionWith(sceneItems.Keys);
        itemCount.Clear();
    }

    internal void EndExitenceCheck()
    {
        if (!loadedAnyItems)
            return;
        if (updateRoutine != null)
            StopCoroutine(updateRoutine);
        foreach (var index in removedItems)
        {
            Destroy(sceneItems[index].gameObject);
            sceneItems.Remove(index);
            itemCache.Remove(index);
        }
        loadedAnyItems = false;
        updateRoutine = StartCoroutine(CreateAllItems());
    }

    Dictionary<int, Item> itemCache = new Dictionary<int, Item>();

    internal void LoadBlock(MapBlock block)
    {
        if (block.items.Count > 0)
            loadedAnyItems = true;
        foreach (var item in block.items)
        {
            removedItems.Remove(item.id);

            itemCache[item.id] = item;
        }
    }

    IEnumerator CreateAllItems()
    {
        var stopWatch = System.Diagnostics.Stopwatch.StartNew();
        foreach (var item in itemCache)
        {
            UpdateItem(item.Value);
            if (stopWatch.ElapsedMilliseconds > 20)
            {
                yield return null;
                stopWatch.Reset();
                stopWatch.Start();
            }
        }
        updateRoutine = null;
    }

    void UpdateItem(Item item)
    {
        ItemModel placedItem;
        if (!sceneItems.ContainsKey(item.id))
        {
            if (itemCount.ContainsKey(item.pos) && itemCount[item.pos] >= GameSettings.Instance.rendering.maxItemsPerTile)
                return;

            placedItem = InstantiateItem(item, transform);
            sceneItems[item.id] = placedItem;
        }
        else
            placedItem = sceneItems[item.id];

        if (itemCount.ContainsKey(item.pos) && itemCount[item.pos] >= GameSettings.Instance.rendering.maxItemsPerTile)
        {
            placedItem.gameObject.SetActive(false);
            return;
        }
        int currentTileCount = 0;
        if (itemCount.ContainsKey(item.pos))
            currentTileCount = itemCount[item.pos];
{'fraction_non_alphanumeric': 0.09387112403100775, 'fraction_numerical': 0.0031492248062015503, 'mean_word_length': 1.8770034843205574, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5000117', 'n_tokens_mistral': 2232, 'n_tokens_neox': 2151, 'n_words': 454}