예제 #1
0
        private ResolvedValue GetRefValue(string refName, Cache cache, string parent, IResolver resolver, IFormatter formatter = null)
        {
            if (refName.Length > 1 && refName[0] == '~')
            {
                refName = refName.Substring(1);
            }

            string fullRefName = parent + "." + refName;
            Entity refAttrib;

            try
            {
                refAttrib = resolver.FindEntity(fullRefName);
                var refValue = new ResolvedValue(fullRefName, refAttrib.Type, refAttrib.Value);
                try
                {
                    resolver.Resolve(refValue, cache);
                }
                catch (Exception e)
                {
                    throw new Exception($"references unresolvable attribute '{refName}': {e.Message}");
                }

                return(refValue);
            }
            catch (Exception)
            {
                // Allow an unknown attribute if it's in the cache (might be a temporary attribute created by a mod)
                try
                {
                    return(cache.GetValue(fullRefName));
                }
                catch
                {
                    // do nothing
                }

                if (formatter != null)
                {
                    // Might be a complete entity rather than an attribute
                    Entity refEntity;
                    try
                    {
                        refEntity = resolver.FindEntity(refName);
                        // The value is the entity in JSON format
                        string strValue = formatter.EntityToJson(refEntity, cache);
                        var    refValue = new ResolvedValue("", Entity.Types.OBJ, strValue);
                        refValue.SetValue(strValue);
                        return(refValue);
                    }
                    catch (Exception)
                    {
                        throw new Exception($"references unknown attribute or entity '{refName}'");
                    }
                }

                throw new Exception($"references unknown attribute '{refName}'");
            }
        }
예제 #2
0
        /// <summary>
        /// Sample function
        ///
        /// The sample function has a circular dependency on the resolver (so we can
        /// have samples based on the gender of other fields which may not be resolved
        /// yet) so we have to pass the resolver in as a parameter.
        /// </summary>
        public string FuncSample(string called, string[] args, Cache cache, string parent, IResolver resolver,
                                 out Sample.Genders gender)
        {
            string help = "Use func.sample(--help) for help.";

            if (args.Length == 1 && args[0].Equals("--help", StringComparison.CurrentCultureIgnoreCase))
            {
                // Show usage
                string usage = "Usage: func.sample(arg1, [arg2]) where arg1 is the name of the samples file to use and arg2 is " +
                               "either another attribute to take the gender from, or M or F to use a fixed gender.";
                throw new Exception(usage);
            }

            if (args.Length < 1 || args.Length > 2)
            {
                throw new Exception($"{called} has bad number of arguments. {help}");
            }

            if (args[0].Length == 0)
            {
                throw new Exception($"{called} has empty argument. {help}");
            }

            gender = Sample.Genders.NEUTRAL;
            if (args.Length == 2)
            {
                if (args[1].Equals("M", StringComparison.CurrentCultureIgnoreCase))
                {
                    gender = Sample.Genders.MALE;
                }
                else if (args[1].Equals("F", StringComparison.CurrentCultureIgnoreCase))
                {
                    gender = Sample.Genders.FEMALE;
                }
                else
                {
                    // Inherit gender from referenced attribute.
                    string refName;
                    if (args[1].Length > 1 && args[1][0] == '~')
                    {
                        refName = parent + "." + args[1].Substring(1);
                    }
                    else
                    {
                        refName = parent + "." + args[1];
                    }

                    Entity refAttrib;
                    try
                    {
                        refAttrib = resolver.FindEntity(refName);
                    }
                    catch (Exception)
                    {
                        throw new Exception($"{called} references unknown attribute '{refName}'");
                    }

                    var refValue = new ResolvedValue(refName, refAttrib.Type, refAttrib.Value);
                    try
                    {
                        resolver.Resolve(refValue, cache);
                    }
                    catch (Exception e)
                    {
                        throw new Exception($"{called} references unresolvable attribute '{refName}': {e.Message}");
                    }

                    gender = refValue.Gender;
                }
            }

            var samples = resolver.GetSamples(args[0]);
            var sample  = samples.Pick(gender);

            gender = sample.Gender;
            return(sample.Value);
        }