示例#1
0
        static MoneyResolver()
        {
            var items = new Tuple <Money, MoneyStatus, int>[] {
                Tuple.Create(Money.Coin10, MoneyStatus.Available, 10),
                Tuple.Create(Money.Coin50, MoneyStatus.Available, 50),
                Tuple.Create(Money.Coin100, MoneyStatus.Available, 100),
                Tuple.Create(Money.Coin500, MoneyStatus.Available, 500),
                Tuple.Create(Money.Bill1000, MoneyStatus.Available, 1000),
                Tuple.Create(Money.Coin1, MoneyStatus.Unavailable, 1),
                Tuple.Create(Money.Coin5, MoneyStatus.Unavailable, 5),
                Tuple.Create(Money.Bill2000, MoneyStatus.Unavailable, 2000),
                Tuple.Create(Money.Bill5000, MoneyStatus.Unavailable, 5000),
                Tuple.Create(Money.Bill10000, MoneyStatus.Unavailable, 10000),
            };

            sLookup = items
                      .ToDictionary(item => item.Item1, item => {
                return(new InternalMoney {
                    Type = item.Item1,
                    Status = item.Item2,
                    Value = item.Item3
                });
            })
            ;

            sUnknownMoney = new InternalMoney {
                Type   = Money.Unknown,
                Status = MoneyStatus.Unavailable,
                Value  = 0
            };
        }
        public void TestToDictionaryKeyError()
        {
            Tuple<int, string>[] records = new Tuple<int, string>[]
            {
                Tuple.Create(1,"cheka"),
                Tuple.Create(1,"duplicated")
            };

            // !!!!!!!!! will throw exception due to same key existed
            IDictionary<int, string> dict = records.ToDictionary(t => t.Item1, t => t.Item2);
        }
        public void TestToDictionaryKeyError()
        {
            Tuple <int, string>[] records = new Tuple <int, string>[]
            {
                Tuple.Create(1, "cheka"),
                Tuple.Create(1, "duplicated")
            };

            // !!!!!!!!! will throw exception due to same key existed
            IDictionary <int, string> dict = records.ToDictionary(t => t.Item1, t => t.Item2);
        }
        public static SortedList<string, double[]> RandomEnvironment(Random rnd)
        {
            var environmentArray = new Tuple<string, double[]>[]
                {
                    Tuple.Create("ce1", Common.RandomDoubleArray(rnd,3)),
                    Tuple.Create("ce2", Common.RandomDoubleArray(rnd, 7))
                };

            var environmentDictionary = environmentArray.ToDictionary(l => l.Item1, l => l.Item2);

            return new SortedList<string, double[]>(environmentDictionary);
        }
示例#5
0
        public static SortedList <string, double> RandomGlobalDiagnosticVariables(Random rnd)
        {
            var globalDiagnosticVariablesArray = new Tuple <string, double>[]
            {
                Tuple.Create(Common.RandomString(rnd, 4), rnd.NextDouble()),
                Tuple.Create(Common.RandomString(rnd, 5), rnd.NextDouble())
            };

            var globalDiagnosticVariablesDictionary = globalDiagnosticVariablesArray.ToDictionary(l => l.Item1, l => l.Item2);

            return(new SortedList <string, double>(globalDiagnosticVariablesDictionary));
        }
示例#6
0
        public static SortedList <string, double[]> RandomEnvironment(Random rnd)
        {
            var environmentArray = new Tuple <string, double[]>[]
            {
                Tuple.Create("ce1", Common.RandomDoubleArray(rnd, 3)),
                Tuple.Create("ce2", Common.RandomDoubleArray(rnd, 7))
            };

            var environmentDictionary = environmentArray.ToDictionary(l => l.Item1, l => l.Item2);

            return(new SortedList <string, double[]>(environmentDictionary));
        }
        public static SortedList<string, double> RandomGlobalDiagnosticVariables(Random rnd)
        {
            var globalDiagnosticVariablesArray = new Tuple<string, double>[]
                {
                    Tuple.Create(Common.RandomString(rnd, 4), rnd.NextDouble()),
                    Tuple.Create(Common.RandomString(rnd, 5), rnd.NextDouble())
                };

            var globalDiagnosticVariablesDictionary = globalDiagnosticVariablesArray.ToDictionary(l => l.Item1, l => l.Item2);

            return new SortedList<string, double>(globalDiagnosticVariablesDictionary);
        }
        /// <summary>
        /// Record dispersal events in the dispersal tracker
        /// </summary>
        /// <param name="inboundCohorts">The cohorts arriving in a cell in the current time step</param>
        /// <param name="outboundCohorts">The cohorts leaving a cell in the current time step</param>
        /// <param name="outboundCohortWeights">The body masses of cohorts leaving the cell in the current time step</param>
        /// <param name="timestep">The current model time step</param>
        /// <param name="madingleyModelGrid">The model grid</param>
        public void RecordDispersalForACell(uint[, ,] inboundCohorts, uint[, ,] outboundCohorts, List<double>[,] outboundCohortWeights, uint timestep, ModelGrid madingleyModelGrid)
        {
            var count = inboundCohorts.GetLength(0) * inboundCohorts.GetLength(1);

            var copy = new Madingley.Common.GridCellDispersal[count];

            for (var kk = 0; kk < count; kk++)
            {
                var ii = (int)kk / inboundCohorts.GetLength(1);
                var jj = kk % inboundCohorts.GetLength(1);

                var denter =
                    new Tuple<Madingley.Common.CohortsEnterDirection, int>[]
                    {
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.North, (int)inboundCohorts[ii, jj, 0]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.NorthEast, (int)inboundCohorts[ii, jj, 1]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.East, (int)inboundCohorts[ii, jj, 2]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.SouthEast, (int)inboundCohorts[ii, jj, 3]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.South, (int)inboundCohorts[ii, jj, 4]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.SouthWest, (int)inboundCohorts[ii, jj, 5]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.West, (int)inboundCohorts[ii, jj, 6]),
                        Tuple.Create(Madingley.Common.CohortsEnterDirection.NorthWest, (int)inboundCohorts[ii, jj, 7]),
                    };

                var enter = denter.ToDictionary(l => l.Item1, l => l.Item2);

                var dexit =
                    new Tuple<Madingley.Common.CohortsExitDirection, int>[]
                    {
                        Tuple.Create(Madingley.Common.CohortsExitDirection.North, (int)outboundCohorts[ii, jj, 0]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.NorthEast, (int)outboundCohorts[ii, jj, 1]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.East, (int)outboundCohorts[ii, jj, 2]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.SouthEast, (int)outboundCohorts[ii, jj, 3]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.South, (int)outboundCohorts[ii, jj, 4]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.SouthWest, (int)outboundCohorts[ii, jj, 5]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.West, (int)outboundCohorts[ii, jj, 6]),
                        Tuple.Create(Madingley.Common.CohortsExitDirection.NorthWest, (int)outboundCohorts[ii, jj, 7]),
                    };

                var exit = dexit.ToDictionary(l => l.Item1, l => l.Item2);

                var weights = outboundCohortWeights[ii, jj].ToArray();

                var cell = madingleyModelGrid.GetGridCell((uint)ii, (uint)jj);

                var ccell = Converters.ConvertCellData(cell);

                copy[kk] = new Madingley.Common.GridCellDispersal(enter, exit, weights, ccell);
            }

            this.GridCellDispersals = copy;
        }
示例#9
0
        /// <summary>
        /// Record dispersal events in the dispersal tracker
        /// </summary>
        /// <param name="inboundCohorts">The cohorts arriving in a cell in the current time step</param>
        /// <param name="outboundCohorts">The cohorts leaving a cell in the current time step</param>
        /// <param name="outboundCohortWeights">The body masses of cohorts leaving the cell in the current time step</param>
        /// <param name="timestep">The current model time step</param>
        /// <param name="madingleyModelGrid">The model grid</param>
        public void RecordDispersalForACell(uint[, ,] inboundCohorts, uint[, ,] outboundCohorts, List <double>[,] outboundCohortWeights, uint timestep, ModelGrid madingleyModelGrid)
        {
            var count = inboundCohorts.GetLength(0) * inboundCohorts.GetLength(1);

            var copy = new Madingley.Common.GridCellDispersal[count];

            for (var kk = 0; kk < count; kk++)
            {
                var ii = (int)kk / inboundCohorts.GetLength(1);
                var jj = kk % inboundCohorts.GetLength(1);

                var denter =
                    new Tuple <Madingley.Common.CohortsEnterDirection, int>[]
                {
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.North, (int)inboundCohorts[ii, jj, 0]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.NorthEast, (int)inboundCohorts[ii, jj, 1]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.East, (int)inboundCohorts[ii, jj, 2]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.SouthEast, (int)inboundCohorts[ii, jj, 3]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.South, (int)inboundCohorts[ii, jj, 4]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.SouthWest, (int)inboundCohorts[ii, jj, 5]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.West, (int)inboundCohorts[ii, jj, 6]),
                    Tuple.Create(Madingley.Common.CohortsEnterDirection.NorthWest, (int)inboundCohorts[ii, jj, 7]),
                };

                var enter = denter.ToDictionary(l => l.Item1, l => l.Item2);

                var dexit =
                    new Tuple <Madingley.Common.CohortsExitDirection, int>[]
                {
                    Tuple.Create(Madingley.Common.CohortsExitDirection.North, (int)outboundCohorts[ii, jj, 0]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.NorthEast, (int)outboundCohorts[ii, jj, 1]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.East, (int)outboundCohorts[ii, jj, 2]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.SouthEast, (int)outboundCohorts[ii, jj, 3]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.South, (int)outboundCohorts[ii, jj, 4]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.SouthWest, (int)outboundCohorts[ii, jj, 5]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.West, (int)outboundCohorts[ii, jj, 6]),
                    Tuple.Create(Madingley.Common.CohortsExitDirection.NorthWest, (int)outboundCohorts[ii, jj, 7]),
                };

                var exit = dexit.ToDictionary(l => l.Item1, l => l.Item2);

                var weights = outboundCohortWeights[ii, jj].ToArray();

                var cell = madingleyModelGrid.GetGridCell((uint)ii, (uint)jj);

                var ccell = Converters.ConvertCellData(cell);

                copy[kk] = new Madingley.Common.GridCellDispersal(enter, exit, weights, ccell);
            }

            this.GridCellDispersals = copy;
        }
        public void Setup()
        {
            //TODO: this became an integration test - proper ProjectionCoreService and ProjectionManager testing is required as well
            _bus.Subscribe(_consumer);

            _processingQueues = GivenProcessingQueues();
            var queues = _processingQueues.ToDictionary(v => v.Item5, v => (IPublisher)v.Item1);
            _managerMessageDispatcher = new ProjectionManagerMessageDispatcher(queues);
            _manager = new ProjectionManager(
                GetInputQueue(),
                GetInputQueue(),
                queues,
                _timeProvider,
                ProjectionType.All,
                _ioDispatcher,
                _initializeSystemProjections);

            _coordinator = new ProjectionCoreCoordinator(
                ProjectionType.All,
                ProjectionCoreWorkersNode.CreateTimeoutSchedulers(queues.Count),
                queues.Values.ToArray(),
                _bus,
                Envelope);

            _bus.Subscribe<ProjectionManagementMessage.Internal.CleanupExpired>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Internal.Deleted>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.Started>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.Stopped>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.Prepared>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.Faulted>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.StateReport>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.ResultReport>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.StatisticsReport>(_manager);
            _bus.Subscribe<CoreProjectionManagementMessage.SlaveProjectionReaderAssigned>(_manager);
            _bus.Subscribe<CoreProjectionStatusMessage.ProjectionWorkerStarted>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.Post>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.UpdateQuery>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.GetQuery>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.Delete>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.GetStatistics>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.GetState>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.GetResult>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.Disable>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.Enable>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.Abort>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.SetRunAs>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.Reset>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.Command.StartSlaveProjections>(_manager);
            _bus.Subscribe<ClientMessage.WriteEventsCompleted>(_manager);
            _bus.Subscribe<ClientMessage.ReadStreamEventsBackwardCompleted>(_manager);
            _bus.Subscribe<ClientMessage.DeleteStreamCompleted>(_manager);
            _bus.Subscribe<SystemMessage.StateChangeMessage>(_manager);
            _bus.Subscribe<SystemMessage.SystemCoreReady>(_manager);
            _bus.Subscribe<ProjectionManagementMessage.ReaderReady>(_manager);
            _bus.Subscribe(
                CallbackSubscriber.Create<ProjectionManagementMessage.Starting>(
                    starting => _queue.Publish(new ProjectionManagementMessage.ReaderReady())));

            _bus.Subscribe<SystemMessage.StateChangeMessage>(_coordinator);
            _bus.Subscribe<SystemMessage.SystemCoreReady>(_coordinator);

            if (GetInputQueue() != _processingQueues.First().Item2)
            {
                _bus.Subscribe<PartitionProcessingResultBase>(_managerMessageDispatcher);
                _bus.Subscribe<CoreProjectionManagementControlMessage>(
                    _managerMessageDispatcher);
                _bus.Subscribe<PartitionProcessingResultOutputBase>(_managerMessageDispatcher);
                _bus.Subscribe<ReaderSubscriptionManagement.SpoolStreamReading>(_managerMessageDispatcher);
            }

            foreach(var q in _processingQueues)
                SetUpCoreServices(q.Item5, q.Item1, q.Item2, q.Item3, q.Item4);

            //Given();
            WhenLoop();
        }
示例#11
0
        static MoneyResolver()
        {
            var items = new Tuple<Money, MoneyStatus, int>[] {
                Tuple.Create(Money.Coin10    , MoneyStatus.Available,   10),
                Tuple.Create(Money.Coin50    , MoneyStatus.Available,   50),
                Tuple.Create(Money.Coin100   , MoneyStatus.Available,   100),
                Tuple.Create(Money.Coin500   , MoneyStatus.Available,   500),
                Tuple.Create(Money.Bill1000  , MoneyStatus.Available,   1000),
                Tuple.Create(Money.Coin1     , MoneyStatus.Unavailable, 1),
                Tuple.Create(Money.Coin5     , MoneyStatus.Unavailable, 5),
                Tuple.Create(Money.Bill2000  , MoneyStatus.Unavailable, 2000),
                Tuple.Create(Money.Bill5000  , MoneyStatus.Unavailable, 5000),
                Tuple.Create(Money.Bill10000 , MoneyStatus.Unavailable, 10000),
            };

            sLookup = items
                .ToDictionary(item => item.Item1, item => {
                    return new InternalMoney {
                        Type = item.Item1,
                        Status = item.Item2,
                        Value = item.Item3
                    };
                })
            ;

            sUnknownMoney = new InternalMoney {
                Type = Money.Unknown,
                Status = MoneyStatus.Unavailable,
                Value = 0
            };
        }
示例#12
0
        public static Look Parse(string str)
        {
            if (string.IsNullOrEmpty(str) || str[0] != '{')
            {
                Console.WriteLine("Incorrect EntityLook format : {0}", str);
                return(new Look());
            }
            int i   = 1;
            int num = str.IndexOf('|');

            if (num == -1)
            {
                num = str.IndexOf("}");
                if (num == -1)
                {
                    throw new System.Exception("Incorrect EntityLook format : " + str);
                }
            }
            uint bones = uint.Parse(str.Substring(i, num - i));

            i = num + 1;
            uint[] skins = new uint[0];
            if ((num = str.IndexOf('|', i)) != -1 || (num = str.IndexOf('}', i)) != -1)
            {
                skins = Look.ParseCollection <uint>(str.Substring(i, num - i), new Func <string, uint>(uint.Parse));
                i     = num + 1;
            }
            Tuple <int, int>[] source = new Tuple <int, int> [0];
            if ((num = str.IndexOf('|', i)) != -1 || (num = str.IndexOf('}', i)) != -1)
            {
                source = Look.ParseCollection <Tuple <int, int> >(str.Substring(i, num - i), new Func <string, Tuple <int, int> >(Look.ParseIndexedColor));
                i      = num + 1;
            }
            int[] scales = new int[0];
            if ((num = str.IndexOf('|', i)) != -1 || (num = str.IndexOf('}', i)) != -1)
            {
                scales = Look.ParseCollection <int>(str.Substring(i, num - i), new Func <string, int>(int.Parse));
                i      = num + 1;
            }
            List <SubLook> list = new List <SubLook>();

            while (i < str.Length)
            {
                int  num2     = str.IndexOf('@', i, 3);
                int  num3     = str.IndexOf('=', num2 + 1, 3);
                byte category = byte.Parse(str.Substring(i, num2 - i));
                byte b        = byte.Parse(str.Substring(num2 + 1, num3 - (num2 + 1)));
                int  num4     = 0;
                int  num5     = num3 + 1;
                System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
                do
                {
                    stringBuilder.Append(str[num5]);
                    if (str[num5] == '{')
                    {
                        num4++;
                    }
                    else
                    {
                        if (str[num5] == '}')
                        {
                            num4--;
                        }
                    }
                    num5++;
                }while (num4 > 0);
                list.Add(new SubLook((sbyte)b, (SubEntityBindingPointCategoryEnum)category, Look.Parse(stringBuilder.ToString())));
                i = num5 + 1;
            }
            return(new Look(bones, skins, source.ToDictionary((Tuple <int, int> x) => x.Item1, (Tuple <int, int> x) => x.Item2), scales, list.ToArray()));
        }
示例#13
0
        public static ActorLook Parse(string str)
        {
            if (string.IsNullOrEmpty(str) || str[0] != '{')
            {
                throw new Exception("Incorrect EntityLook format : " + str);
            }

            var cursorPos    = 1;
            var separatorPos = str.IndexOf('|');

            if (separatorPos == -1)
            {
                separatorPos = str.IndexOf("}");

                if (separatorPos == -1)
                {
                    throw new Exception("Incorrect EntityLook format : " + str);
                }
            }

            var bonesId = short.Parse(str.Substring(cursorPos, separatorPos - cursorPos));

            cursorPos = separatorPos + 1;

            var skins = new short[0];

            if ((separatorPos = str.IndexOf('|', cursorPos)) != -1 ||
                (separatorPos = str.IndexOf('}', cursorPos)) != -1)
            {
                skins     = ParseCollection(str.Substring(cursorPos, separatorPos - cursorPos), short.Parse);
                cursorPos = separatorPos + 1;
            }

            var colors = new Tuple <int, int> [0];

            if ((separatorPos = str.IndexOf('|', cursorPos)) != -1 ||
                (separatorPos = str.IndexOf('}', cursorPos)) != -1)    // if false there are no informations between the two separators
            {
                colors    = ParseCollection(str.Substring(cursorPos, separatorPos - cursorPos), ParseIndexedColor);
                cursorPos = separatorPos + 1;
            }

            var scales = new short[0];

            if ((separatorPos = str.IndexOf('|', cursorPos)) != -1 ||
                (separatorPos = str.IndexOf('}', cursorPos)) != -1)    // if false there are no informations between the two separators
            {
                scales    = ParseCollection(str.Substring(cursorPos, separatorPos - cursorPos), short.Parse);
                cursorPos = separatorPos + 1;
            }

            var subEntities = new List <SubActorLook>();

            while (cursorPos < str.Length && (str.Length - cursorPos) >= 3)
            {
                var atSeparatorIndex     = str.IndexOf('@', cursorPos, 3);            // max size of a byte = 255, so 3 characters
                var equalsSeparatorIndex = str.IndexOf('=', atSeparatorIndex + 1, 3); // max size of a byte = 255, so 3 characters
                var category             = byte.Parse(str.Substring(cursorPos, atSeparatorIndex - cursorPos));
                var index = byte.Parse(str.Substring(atSeparatorIndex + 1, equalsSeparatorIndex - (atSeparatorIndex + 1)));

                var hookDepth = 0;
                var i         = equalsSeparatorIndex + 1;
                var subEntity = new StringBuilder();
                do
                {
                    subEntity.Append(str[i]);

                    switch (str[i])
                    {
                    case '{':
                        hookDepth++;
                        break;

                    case '}':
                        hookDepth--;
                        break;
                    }

                    i++;
                } while (hookDepth > 0);

                subEntities.Add(new SubActorLook((sbyte)index, (SubEntityBindingPointCategoryEnum)category, Parse(subEntity.ToString())));

                cursorPos = i + 1; // ignore the comma and the last '}' char
            }

            return(new ActorLook(bonesId, skins, colors.ToDictionary(x => x.Item1, x => Color.FromArgb(x.Item2)), scales, subEntities.ToArray()));
        }
        public static ActorLook Parse(string str, bool isMorph = false)
        {
            if (string.IsNullOrEmpty(str) || str[0] != '{')
            {
                NLog.LogManager.GetCurrentClassLogger().Error("Incorrect EntityLook format : {0}", str);
                return(new ActorLook());
            }
            int i   = 1;
            int num = str.IndexOf('|');

            if (num == -1)
            {
                num = str.IndexOf("}");
                if (num == -1)
                {
                    throw new System.Exception("Incorrect EntityLook format : " + str);
                }
            }
            short bones = short.Parse(str.Substring(i, num - i));

            i = num + 1;
            short[] skins = new short[0];
            if ((num = str.IndexOf('|', i)) != -1 || (num = str.IndexOf('}', i)) != -1)
            {
                skins = ActorLook.ParseCollection <short>(str.Substring(i, num - i), new Func <string, short>(short.Parse));
                i     = num + 1;
            }
            Tuple <int, int>[] source = new Tuple <int, int> [0];
            if ((num = str.IndexOf('|', i)) != -1 || (num = str.IndexOf('}', i)) != -1)
            {
                source = ActorLook.ParseCollection <Tuple <int, int> >(str.Substring(i, num - i), new Func <string, Tuple <int, int> >(ActorLook.ParseIndexedColor));
                i      = num + 1;
            }
            short[] scales = new short[0];
            if ((num = str.IndexOf('|', i)) != -1 || (num = str.IndexOf('}', i)) != -1)
            {
                scales = ActorLook.ParseCollection <short>(str.Substring(i, num - i), new Func <string, short>(short.Parse));
                i      = num + 1;
            }
            System.Collections.Generic.List <SubActorLook> list = new System.Collections.Generic.List <SubActorLook>();
            while (i < str.Length)
            {
                int  num2     = str.IndexOf('@', i, 3);
                int  num3     = str.IndexOf('=', num2 + 1, 3);
                byte category = byte.Parse(str.Substring(i, num2 - i));
                byte b        = byte.Parse(str.Substring(num2 + 1, num3 - (num2 + 1)));
                int  num4     = 0;
                int  num5     = num3 + 1;
                System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
                do
                {
                    stringBuilder.Append(str[num5]);
                    if (str[num5] == '{')
                    {
                        num4++;
                    }
                    else
                    {
                        if (str[num5] == '}')
                        {
                            num4--;
                        }
                    }
                    num5++;
                }while (num4 > 0);
                list.Add(new SubActorLook((sbyte)b, (SubEntityBindingPointCategoryEnum)category, ActorLook.Parse(stringBuilder.ToString())));
                i = num5 + 1;
            }
            return(new ActorLook(bones, skins, source.ToDictionary((Tuple <int, int> x) => x.Item1, (Tuple <int, int> x) => Color.FromArgb(x.Item2)), scales, list.ToArray(), isMorph));
        }