public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            /////////////////Early Out//////////////////////
            if (GetIfIsTopDown(element) == false)
            {
                return(codeBlock);
            }
            //////////////End Early Out//////////////////////
            ///
            codeBlock.Line("#region Top Down Fields");


            codeBlock.Line("DataTypes.TopDownValues mCurrentMovement;");
            codeBlock.Line("public float TopDownSpeedMultiplier { get; set; } = 1;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The current movement variables used when applying input.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("public DataTypes.TopDownValues", "CurrentMovement")
            .Get()
            .Line("return mCurrentMovement;");

            codeBlock.Property("public FlatRedBall.Input.IInputDevice", "InputDevice")
            .Line("get;")
            .Line("private set;");

            codeBlock.Line("TopDownDirection mDirectionFacing;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Which direciton the character is facing.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("protected TopDownDirection", "DirectionFacing")
            .Get()
            .Line("return mDirectionFacing;");

            codeBlock.Property("public PossibleDirections", "PossibleDirections")
            .AutoGet().End()
            .AutoSet();

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The input object which controls the horizontal movement of the character.");
            codeBlock.Line("/// Common examples include a d-pad, analog stick, or keyboard keys.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public FlatRedBall.Input.I2DInput", "MovementInput");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Whether input is read to control the movement of the character.");
            codeBlock.Line("/// This can be turned off if the player should not be able to control");
            codeBlock.Line("/// the character.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public bool", "InputEnabled");

            codeBlock.Line("#endregion");

            return(codeBlock);
        }
        private void GenerateVariable(ICodeBlock currentBlock, string propertyName, Gum.DataTypes.Variables.VariableSave variable, ElementSave elementSave)
        {
            #region Get Variable Type
            string variableType = variable.Type;

            string unmodifiedVariableType = variableType;

            if (GueDerivingClassCodeGenerator.Self.TypeToQualifiedTypes.ContainsKey(variableType))
            {
                variableType = GueDerivingClassCodeGenerator.Self.TypeToQualifiedTypes[variableType];
            }

            if (variable.IsFile && variable.GetRootName() == "SourceFile")
            {
                variableType = "Microsoft.Xna.Framework.Graphics.Texture2D";
            }

            #endregion

            ICodeBlock property = currentBlock.Property("public " + variableType, variable.Name.Replace(" ", ""));


            string variableName = variable.Name;
            if (mStandardVariableNameAliases.ContainsKey(variableName.Replace(" ", "")))
            {
                variableName = mStandardVariableNameAliases[variableName.Replace(" ", "")];
            }

            string whatToGetOrSet = propertyName + "." + variableName.Replace(" ", "");

            GenerateGetter(propertyName, variable, property, variableName, whatToGetOrSet, elementSave);

            GenerateSetter(propertyName, variable, property, variableName, whatToGetOrSet, elementSave);
        }
        private string CreateContainedObjectMembers(ICodeBlock currentBlock, ElementSave standardElementSave)
        {
            string qualifiedBaseType   = mStandardElementToQualifiedTypes[standardElementSave.Name];
            string unqualifiedBaseType = standardElementSave.Name;

            string fieldName = "mContained" + unqualifiedBaseType;

            currentBlock.Line(qualifiedBaseType + " " + fieldName + ";");

            string propertyName = "Contained" + unqualifiedBaseType;

            var containedProperty = currentBlock.Property(qualifiedBaseType, propertyName);

            {
                var get = containedProperty.Get();
                {
                    var ifBlock = get.If(fieldName + " == null");
                    {
                        ifBlock.Line(fieldName + " = this.RenderableComponent as " + qualifiedBaseType + ";");
                    }

                    get.Line("return " + fieldName + ";");
                }
            }
            return(propertyName);
        }
Beispiel #4
0
        private string CreateContainedObjectMembers(ICodeBlock currentBlock, ElementSave standardElementSave)
        {
            if (mStandardElementToQualifiedTypes.ContainsKey(standardElementSave.Name) == false)
            {
                throw new InvalidOperationException($"The {nameof(mStandardElementToQualifiedTypes)} " +
                                                    $"does not contain the key {standardElementSave.Name}");
            }
            string qualifiedBaseType   = mStandardElementToQualifiedTypes[standardElementSave.Name];
            string unqualifiedBaseType = standardElementSave.Name;

            string fieldName = "mContained" + unqualifiedBaseType;

            currentBlock.Line(qualifiedBaseType + " " + fieldName + ";");

            string propertyName = "Contained" + unqualifiedBaseType;

            var containedProperty = currentBlock.Property(qualifiedBaseType, propertyName);

            {
                var get = containedProperty.Get();
                {
                    var ifBlock = get.If(fieldName + " == null");
                    {
                        ifBlock.Line(fieldName + " = this.RenderableComponent as " + qualifiedBaseType + ";");
                    }

                    get.Line("return " + fieldName + ";");
                }
            }
            return(propertyName);
        }
        private static void GenerateVisibleProperty(ICodeBlock codeBlock, IElement element, EntitySave entitySave)
        {
            bool inheritsFromIVisible = entitySave.GetInheritsFromIVisible();

            #region Get whether we use virtual or override

            if (!inheritsFromIVisible)
            {
                codeBlock.Line("protected bool mVisible = true;");
            }

            #endregion

            var prop = codeBlock.Property("Visible", Public: true, Override: entitySave.GetInheritsFromIVisible(), Virtual: !entitySave.GetInheritsFromIVisible(), Type: "bool");

            if (inheritsFromIVisible)
            {
                prop.Get()
                .Line("return base.Visible;");
            }
            else
            {
                prop.Get()
                .Line("return mVisible;");
            }
            var set = prop.Set();

            #region History on the before set code

            // See comment above about why we no longer
            // check to see if it creates an event.
            //if (createsVisibleEvent)
            //{
            // Keep hasChanged around just in case we want to make a Changed event.  It won't be used by the Set event
            // Update November 27, 2011
            // This is just polluting code.  Let's remove it for now
            //set.Line("bool hasChanged = value != mVisible;");
            #endregion

            EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.Before, "Visible", entitySave);

            if (entitySave.GetInheritsFromIVisible())
            {
                set.Line("base.Visible = value;");
            }
            else
            {
                set.Line("mVisible = value;");
            }

            // May 6, 2012
            // We used to manually
            // set the Visible of all
            // children, but now we no
            // longer do that because there
            // is a concept of relative visibility.
            // WriteVisibleSetForNamedObjectSaves(set, entitySave);

            EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.After, "Visible", entitySave);
        }
 internal static ICodeBlock Property(this ICodeBlock pCodeBlock, string pName,
                                     bool Public            = false,
                                     bool Private           = false,
                                     bool Protected         = false,
                                     bool Internal          = false,
                                     bool ProtectedInternal = false,
                                     bool Static            = false,
                                     bool Override          = false,
                                     bool Virtual           = false,
                                     string Type            = null)
 {
     return(pCodeBlock.Property(
                StringHelper.Modifiers(
                    Public: Public,
                    Private: Private,
                    Protected: Protected,
                    Internal: Internal,
                    ProtectedInternal: ProtectedInternal,
                    Static: Static,
                    Override: Override,
                    Virtual: Virtual,
                    Type: Type
                    )
                , pName));
 }
 private void GenerateAbsoluteVisible(ICodeBlock codeBlock, EntitySave entitySave)
 {
     if (!entitySave.GetInheritsFromIVisible())
     {
         var prop = codeBlock.Property("AbsoluteVisible", Public: true, Override: false, Type: "bool");
         prop.Get().Line("return Visible && (Parent == null || IgnoresParentVisibility || Parent is FlatRedBall.Graphics.IVisible == false || (Parent as FlatRedBall.Graphics.IVisible).AbsoluteVisible);");
     }
 }
        private void GenerateAbsoluteVisible(ICodeBlock codeBlock, EntitySave entitySave)
        {
            if (!entitySave.GetInheritsFromIVisible())
            {
                var prop = codeBlock.Property("AbsoluteVisible", Public: true, Override: false, Type: "bool");
                prop.Get().Line("return Visible && (Parent == null || IgnoresParentVisibility || Parent is FlatRedBall.Graphics.IVisible == false || (Parent as FlatRedBall.Graphics.IVisible).AbsoluteVisible);");
            }

        }
Beispiel #9
0
        private void GenerateExposedVariableProperty(ElementSave elementSave, ICodeBlock currentBlock, VariableSave variable)
        {
            string variableType = variable.Type;

            ModifyVariableTypeForProperty(ref variableType, variable, elementSave);

            string propertyName = variable.ExposedAsName.Replace(" ", "_");

            ICodeBlock property = currentBlock.Property("public " + variableType, propertyName);

            string whatToGetOrSet = variable.Name;

            // If this is an exposed property on a standard element, then we just need to kill all spaces and replace
            // them with nothing
            var instance = elementSave.GetInstance(variable.SourceObject);

            if (instance != null)
            {
                var baseElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instance.BaseType);

                if (baseElement != null && baseElement is StandardElementSave)
                {
                    whatToGetOrSet = whatToGetOrSet.Replace(" ", "");
                }

                var rootName = variable.GetRootName();
                if (rootName.EndsWith("State"))
                {
                    var withoutState = rootName.Substring(0, rootName.Length - "State".Length);
                    if (rootName == "State")
                    {
                        whatToGetOrSet = variable.SourceObject + "." + "CurrentVariableState";
                    }
                    else if (baseElement != null && baseElement.Categories.Any(item => item.Name == withoutState))
                    {
                        whatToGetOrSet = variable.SourceObject + ".Current" + withoutState + "State";
                    }
                }
            }

            property.Get()
            .Line("return " + whatToGetOrSet + ";");
            var setter = property.Set();

            if (EventCodeGenerator.Self.GetIfShouldGenerateEventOnVariableSet(elementSave, variable))
            {
                string eventName = EventCodeGenerator.Self.GetEventName(variable, elementSave);

                setter.If($"{whatToGetOrSet} != value")
                .Line(whatToGetOrSet + " = value;")
                .Line($"{eventName}?.Invoke(this, null);");
            }
            else
            {
                setter.Line(whatToGetOrSet + " = value;");
            }
        }
 private void GenerateIVisibleParent(ICodeBlock codeBlock, EntitySave entitySave)
 {
     if (!entitySave.GetInheritsFromIVisible())
     {
         var prop = codeBlock.Property("FlatRedBall.Graphics.IVisible.Parent", Override: false, Type: "FlatRedBall.Graphics.IVisible");
         var get = prop.Get();
         get.If("this.Parent != null && this.Parent is FlatRedBall.Graphics.IVisible")
             .Line("return this.Parent as FlatRedBall.Graphics.IVisible;").End()
             .Else()
             .Line("return null;");
     }
 }
 private void GenerateIVisibleParent(ICodeBlock codeBlock, EntitySave entitySave)
 {
     if (!entitySave.GetInheritsFromIVisible())
     {
         var prop = codeBlock.Property("FlatRedBall.Graphics.IVisible.Parent", Override: false, Type: "FlatRedBall.Graphics.IVisible");
         var get  = prop.Get();
         get.If("this.Parent != null && this.Parent is FlatRedBall.Graphics.IVisible")
         .Line("return this.Parent as FlatRedBall.Graphics.IVisible;").End()
         .Else()
         .Line("return null;");
     }
 }
Beispiel #12
0
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            if (ShouldGenerate(element))
            {
                var entitySave = element as EntitySave;

                // The following are already handled by the Entity:
                // X, Y, Z
                codeBlock.Property("bool", "FlatRedBall.Graphics.IDrawableBatch.UpdateEveryFrame")
                .Get()
                .Line("return false;");
            }

            return(codeBlock);
        }
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            if (ShouldGenerate(element))
            {
                var entitySave = element as EntitySave;

                // The following are already handled by the Entity:
                // X, Y, Z
                codeBlock.Property("bool", "FlatRedBall.Graphics.IDrawableBatch.UpdateEveryFrame")
                    .Get()
                    .Line("return false;");
            }

            return codeBlock;
        }
        private static void GenerateEnabledVariable(ICodeBlock codeBlock, IElement element)
        {
            CustomVariable exposedEnabledVariable  = element.CustomVariables.FirstOrDefault(item => item.Name == "Enabled" && item.Type == "bool");
            bool           isEnableVariableExposed = exposedEnabledVariable != null;

            bool hasEvents = exposedEnabledVariable != null && exposedEnabledVariable.CreatesEvent && element.Events.Any(item => item.SourceVariable == exposedEnabledVariable.Name);

            if (hasEvents)
            {
                EventCodeGenerator.GenerateEventsForVariable(codeBlock, exposedEnabledVariable.Name);
            }

            string prefix;
            string propertyName;

            if (isEnableVariableExposed)
            {
                prefix       = "public bool";
                propertyName = "Enabled";
            }
            else
            {
                prefix       = "bool";
                propertyName = "FlatRedBall.Gui.IWindow.Enabled";
            }

            codeBlock.Line(Resources.Resource1.IWindowTemplate);

            var property = codeBlock.Property(prefix, propertyName);

            property.Get().Line("return mEnabled;");

            var setBlock = property.Set();

            if (hasEvents)
            {
                EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, exposedEnabledVariable.Name, element);
            }

            var setIf = setBlock.If("mEnabled != value");

            setIf.Line("mEnabled = value;");
            setIf.Line("EnabledChange?.Invoke(this);");
            if (hasEvents)
            {
                EventCodeGenerator.GenerateEventRaisingCode(setIf, BeforeOrAfter.After, exposedEnabledVariable.Name, element);
            }
        }
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, SaveClasses.IElement element)
        {
            EntitySave asEntitySave = element as EntitySave;
            if (asEntitySave != null && asEntitySave.ImplementsICollidable)
            {

                codeBlock.Line("private FlatRedBall.Math.Geometry.ShapeCollection mGeneratedCollision;");
                var propBlock = codeBlock.Property("public FlatRedBall.Math.Geometry.ShapeCollection", "Collision");

                propBlock.Get().Line("return mGeneratedCollision;");

                return codeBlock;
            }
            else
            {
                return base.GenerateFields(codeBlock, element);
            }
        }
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, SaveClasses.IElement element)
        {
            EntitySave asEntitySave = element as EntitySave;

            if (asEntitySave != null && asEntitySave.ImplementsICollidable)
            {
                codeBlock.Line("private FlatRedBall.Math.Geometry.ShapeCollection mGeneratedCollision;");
                var propBlock = codeBlock.Property("public FlatRedBall.Math.Geometry.ShapeCollection", "Collision");

                propBlock.Get().Line("return mGeneratedCollision;");

                return(codeBlock);
            }
            else
            {
                return(base.GenerateFields(codeBlock, element));
            }
        }
Beispiel #17
0
        private void GeneratePropertyForCurrentState(ICodeBlock currentBlock, string propertyType, string propertyName, List <Gum.DataTypes.Variables.StateSave> states, ElementSave container)
        {
            var property = currentBlock.Property("public " + propertyType, propertyName);

            property.Get().Line("return m" + propertyName + ";");

            var setter = property.Set();
            {
                setter.Line("m" + propertyName + " = value;");

                var switchBlock = setter.Switch("m" + propertyName);

                foreach (var state in states)
                {
                    var caseBlock = switchBlock.Case(propertyType + "." + state.MemberNameInCode());
                    {
                        foreach (var variable in state.Variables)
                        {
                            // where block doesn't debug well for some reason, so I unrolled it...
                            if (GetIfShouldGenerateStateVariable(variable, container))
                            {
                                // Note that this could return values like "1,2" instead of "1.2" depending
                                // on the current language, so the AdjustVariableValueIfNecessary needs to account for that.
                                string variableValue = variable.Value.ToString();
                                bool   isEntireAssignment;

                                GueDerivingClassCodeGenerator.Self.AdjustVariableValueIfNecessary(variable, container, ref variableValue, out isEntireAssignment);
                                if (isEntireAssignment)
                                {
                                    caseBlock.Line(variableValue);
                                }
                                else
                                {
                                    string memberNameInCode = variable.MemberNameInCode(container, VariableNamesToReplaceForStates);
                                    caseBlock.Line(memberNameInCode + " = " + variableValue + ";");
                                }
                            }
                        }
                    }
                }
            }
        }
        private void GenerateBehaviorStateProperties(ICodeBlock currentBlock, ElementSave elementSave)
        {
            var asComponentSave = elementSave as ComponentSave;

            if (asComponentSave != null)
            {
                foreach (var elementBehavior in asComponentSave.Behaviors)
                {
                    var behavior = Managers.AppState.Self.GumProjectSave.Behaviors
                                   .FirstOrDefault(item => item.Name == elementBehavior.BehaviorName);

                    if (behavior == null)
                    {
                        // user set a behavior, then deleted the behavior. We don't want to generate code for it
                        currentBlock.Line("// No properties generated for behavior because it's not part of the Gum project: " + elementBehavior.BehaviorName);
                    }
                    else
                    {
                        string interfaceType = $"I{behavior.Name}";

                        foreach (var behaviorCategory in behavior.Categories)
                        {
                            string propertyType = $"{behavior.Name}{behaviorCategory.Name}";

                            var propertyBlock = currentBlock.Property($"{propertyType}", $"{interfaceType}.Current{propertyType}State");
                            var setBlock      = propertyBlock.Set();
                            var switchBlock   = setBlock.Switch("value");
                            foreach (var behaviorState in behaviorCategory.States)
                            {
                                var caseBlock = switchBlock.Case($"{behavior.Name}{behaviorCategory.Name}.{behaviorState.Name}");

                                caseBlock.Line($"this.Current{behaviorCategory.Name}State = {behaviorCategory.Name}.{behaviorState.Name};");
                            }
                        }
                    }
                }
            }
        }
        private static ICodeBlock GenerateCurrentStateProperty(IElement element, ICodeBlock codeBlock, string enumType, List <StateSave> states)
        {
            var createField = false;

            if (enumType == "VariableState" && !DoesBaseHaveUncategorizedStates(element))  //Uncategorized and not base
            {
                createField = true;
            }
            else if (enumType != "VariableState")    //Check if this state category exists in a parent entity
            {
                if (element.BaseElement != null)
                {
                    var categories = GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true);

                    if (!categories.Any(category => category == enumType))
                    {
                        createField = true;
                    }
                }
                else
                {
                    createField = true;
                }
            }

            string variableNameModifier = enumType;

            if (enumType == "VariableState")
            {
                variableNameModifier = "";
            }

            string qualifiedEnumType = element.Name.Replace("\\", ".").Replace("/", ".") + "." + enumType;

            if (states.Count != 0)
            {
                string         variableToLookFor = "Current" + variableNameModifier + "State";
                CustomVariable customVariable    = element.GetCustomVariable(variableToLookFor);
                bool           hasEvent          = customVariable != null && customVariable.CreatesEvent;


                #region Header and Getter stuff - simple stuff with no logic

                if (createField)
                {
                    codeBlock
                    .Line(string.Format("protected int mCurrent{0}State = 0;", variableNameModifier));
                }

                string publicWithOptionalNew = "public";
                if (ShouldUseNewKeyword(element, enumType))
                {
                    publicWithOptionalNew += " new";
                }
                var setBlock = codeBlock
                               .Property(publicWithOptionalNew + " " + qualifiedEnumType, "Current" + variableNameModifier + "State")
                               .Get()
                               .If(string.Format("System.Enum.IsDefined(typeof({0}), mCurrent{1}State)", enumType, variableNameModifier))
                               .Line(string.Format("return ({0})mCurrent{1}State;", enumType, variableNameModifier))
                               .End()
                               .Else()
                               .Line(string.Format("return {0}.Unknown;", enumType))
                               .End()
                               .End()
                               .Set();

                #endregion

                #region Set the state value and call an event if necessary

                bool stillNeedsToAssignValue = true;

                if (element is EntitySave)
                {
                    EntitySave asEntitySave = element as EntitySave;

                    //if (!string.IsNullOrEmpty(asEntitySave.CurrentStateChange))
                    //{
                    //    setBlock
                    //        .If("value != mCurrent" + variableNameModifier + "State")
                    //            .Line("mCurrent" + variableNameModifier + "State = value;")
                    //            .Line(asEntitySave.CurrentStateChange + "(this, null);");

                    //    stillNeedsToAssignValue = false;
                    //}
                }

                if (hasEvent)
                {
                    EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, variableToLookFor, element);
                }

                if (stillNeedsToAssignValue)
                {
                    setBlock.Line("mCurrent" + variableNameModifier + "State = (int)value;");
                }

                #endregion

                var switchBlock = setBlock.Switch("Current" + variableNameModifier + "State");

                switchBlock.Case(enumType + ".Uninitialized");
                switchBlock.Case(enumType + ".Unknown");

                foreach (StateSave stateSave in states)
                {
                    GenerateCurrentStateCodeForIndividualState(element, switchBlock, stateSave, enumType);
                }

                if ((enumType == "VariableState" && DoesBaseHaveUncategorizedStates(element)) ||
                    (!string.IsNullOrEmpty(element.BaseElement) && GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true).Any(category => category == enumType)))
                {
                    switchBlock.Default()
                    .Line("base.Current" + variableNameModifier + "State = base.Current" + variableNameModifier + "State;");
                }

                if (hasEvent)
                {
                    EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.After, variableToLookFor, element);
                }
            }
            return(codeBlock);
        }
Beispiel #20
0
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            /////////////////Early Out//////////////////
            if (GetIfIsRacingEntity(element) == false)
            {
                return(codeBlock);
            }
            ///////////////End Early Out///////////////////

            codeBlock.Line("float lateralToForwardTransferRatio;");
            codeBlock.Line("float currentTurnRate;");
            codeBlock.Line("bool IsAllowedToDrive = true;");
            codeBlock.Line("bool wasMovingForwardAtStartOfCollisionRecording;");

            codeBlock.Line("CollisionHistory collisionHistory = new CollisionHistory();");

            var property = codeBlock.Property("public float", "EffectiveStability");
            var get      = property.Get();

            get.Line("var toReturn = CarData.Stability;");
            var ifBlock = get.If("Gas.Value == 0")
                          .Line("toReturn += CarData.NoGasExtraStability;");

            ifBlock = get.If("currentTurnRate == 0")
                      .Line("toReturn += CarData.NoTurnExtraStability;");

            get.Line("return toReturn;");

            codeBlock.AutoProperty("public RacingDirection", "ForwardDirection");

            codeBlock.Property("public Microsoft.Xna.Framework.Vector3", "Forward")
            .Get()
            .Switch("ForwardDirection")
            .CaseNoBreak("RacingDirection.Up")
            .Line("return RotationMatrix.Up;").End()
            .CaseNoBreak("RacingDirection.Right")
            .Line("return RotationMatrix.Right;").End()
            .CaseNoBreak("RacingDirection.Down")
            .Line("return RotationMatrix.Down;").End()
            .CaseNoBreak("RacingDirection.Left")
            .Line("return RotationMatrix.Left;").End()
            .Default()
            .Line("return RotationMatrix.Up;").End();

            codeBlock.Property("public Microsoft.Xna.Framework.Vector3", "Right")
            .Get()
            .Switch("ForwardDirection")
            .CaseNoBreak("RacingDirection.Up")
            .Line("return RotationMatrix.Right;").End()
            .CaseNoBreak("RacingDirection.Right")
            .Line("return RotationMatrix.Down;").End()
            .CaseNoBreak("RacingDirection.Down")
            .Line("return RotationMatrix.Left;").End()
            .CaseNoBreak("RacingDirection.Left")
            .Line("return RotationMatrix.Up;")
            .Default()
            .Line("return RotationMatrix.Right;").End();

            codeBlock.Property("public Microsoft.Xna.Framework.Vector3", "Left")
            .Get()
            .Switch("ForwardDirection")
            .CaseNoBreak("RacingDirection.Up")
            .Line("return RotationMatrix.Left;").End()
            .CaseNoBreak("RacingDirection.Right")
            .Line("return RotationMatrix.Up;").End()
            .CaseNoBreak("RacingDirection.Down")
            .Line("return RotationMatrix.Right;").End()
            .CaseNoBreak("RacingDirection.Left")
            .Line("return RotationMatrix.Down;")
            .Default()
            .Line("return RotationMatrix.Left;").End();

            codeBlock.AutoProperty("private FlatRedBall.Input.I1DInput", "Gas");
            codeBlock.AutoProperty("private FlatRedBall.Input.IPressableInput", "Brake");
            codeBlock.AutoProperty("private FlatRedBall.Input.I1DInput", "SteeringInput");

            codeBlock.Line("public FlatRedBall.Input.IInputDevice InputDevice { get; private set; }");

            codeBlock.Property("public float", "CurrentForwardSpeed")
            .Get()
            .Line("return Microsoft.Xna.Framework.Vector3.Dot(this.Velocity, this.Forward);");

            codeBlock.Property("public float", "CurrentLateralSpeed")
            .Get()
            .Line("return Microsoft.Xna.Framework.Vector3.Dot(this.Velocity, this.Right);");

            GenerateInitializeInput(codeBlock);

            GenerateLateralSpeedAdjustmentActivityMethod(codeBlock);

            GenerateForwardBackActivityMethod(codeBlock);

            GenerateTurningActivity(codeBlock);

            GenerateBeforeAfterCollisionLogic(codeBlock);

            return(codeBlock);

            /*
             *
             *
             * public bool IsAllowedToDrive
             * {
             * get; set;
             * } = true;
             */
        }
        private static void GenerateEnabledVariable(ICodeBlock codeBlock, IElement element)
        {
            CustomVariable exposedEnabledVariable = element.CustomVariables.FirstOrDefault(item => item.Name == "Enabled" && item.Type == "bool");
            bool isEnableVariableExposed = exposedEnabledVariable != null;

            bool hasEvents = exposedEnabledVariable != null && exposedEnabledVariable.CreatesEvent && element.Events.Any(item => item.SourceVariable == exposedEnabledVariable.Name);

            if (hasEvents)
            {
                EventCodeGenerator.GenerateEventsForVariable(codeBlock, exposedEnabledVariable.Name);
            }

            string prefix;
            string propertyName;
            if (isEnableVariableExposed)
            {
                prefix = "public bool";
                propertyName = "Enabled";
            }
            else
            {
                prefix = "bool";
                propertyName = "FlatRedBall.Gui.IWindow.Enabled";
            }

            codeBlock.Line(Resources.Resource1.IWindowTemplate);

            var property = codeBlock.Property(prefix, propertyName);

            property.Get().Line("return mEnabled;");

            var setBlock = property.Set();
            if (hasEvents)
            {
                EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, exposedEnabledVariable.Name, element);
            }

            var setIf = setBlock.If("mEnabled != value");
            setIf.Line("mEnabled = value;");
            setIf.Line("EnabledChange?.Invoke(this);");
            if (hasEvents)
            {
                EventCodeGenerator.GenerateEventRaisingCode(setIf, BeforeOrAfter.After, exposedEnabledVariable.Name, element);
            }
        }
Beispiel #22
0
        public override void GenerateAdditionalClasses(ICodeBlock codeBlock, IElement element)
        {
            /////////////////Early Out//////////////////////
            if (TopDownEntityPropertyLogic.GetIfIsTopDown(element) == false)
            {
                return;
            }
            //////////////End Early Out//////////////////////
            ///

            var className = element.GetStrippedName();

            codeBlock = codeBlock.Class("public partial", className, ": TopDown.ITopDownEntity");

            codeBlock.Line("#region Top Down Fields");

            WriteAnimationFields(element, codeBlock);

            codeBlock.Line("DataTypes.TopDownValues mCurrentMovement;");
            codeBlock.Line("public float TopDownSpeedMultiplier { get; set; } = 1;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The current movement variables used when applying input.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("public DataTypes.TopDownValues", "CurrentMovement")
            .Get()
            .Line("return mCurrentMovement;").End()
            .Set("private")
            .Line("mCurrentMovement = value;");


            codeBlock.Property("public FlatRedBall.Input.IInputDevice", "InputDevice")
            .Line("get;")
            .Line("private set;");

            codeBlock.Line("TopDownDirection mDirectionFacing;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Which direciton the character is facing.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("public TopDownDirection", "DirectionFacing")
            .Get()
            .Line("return mDirectionFacing;");

            codeBlock.Property("public PossibleDirections", "PossibleDirections")
            .AutoGet().End()
            .AutoSet();

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The input object which controls the horizontal movement of the character.");
            codeBlock.Line("/// Common examples include a d-pad, analog stick, or keyboard keys.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public FlatRedBall.Input.I2DInput", "MovementInput");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Whether input is read to control the movement of the character.");
            codeBlock.Line("/// This can be turned off if the player should not be able to control");
            codeBlock.Line("/// the character.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public bool", "InputEnabled");

            codeBlock.Line("TopDown.DirectionBasedAnimationLayer mTopDownAnimationLayer;");


            codeBlock.Line("#endregion");
        }
        private static void GenerateVisibleProperty(ICodeBlock codeBlock, IElement element, EntitySave entitySave)
        {
            bool inheritsFromIVisible = entitySave.GetInheritsFromIVisible();

            #region Get whether we use virtual or override

            if (!inheritsFromIVisible)
            {
                codeBlock.Line("protected bool mVisible = true;");
            }

            #endregion

            var prop = codeBlock.Property("Visible", Public: true, Override: entitySave.GetInheritsFromIVisible(), Virtual: !entitySave.GetInheritsFromIVisible(), Type: "bool");

            if (inheritsFromIVisible)
            {
                prop.Get()
                    .Line("return base.Visible;");
            }
            else
            {
                prop.Get()
                    .Line("return mVisible;");
            }
            var set = prop.Set();

            #region History on the before set code

            // See comment above about why we no longer
            // check to see if it creates an event.
            //if (createsVisibleEvent)
            //{
            // Keep hasChanged around just in case we want to make a Changed event.  It won't be used by the Set event
            // Update November 27, 2011
            // This is just polluting code.  Let's remove it for now
            //set.Line("bool hasChanged = value != mVisible;");
            #endregion

            EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.Before, "Visible", entitySave);

            if (entitySave.GetInheritsFromIVisible())
            {
                set.Line("base.Visible = value;");
            }
            else
            {
                set.Line("mVisible = value;");
            }

            // May 6, 2012
            // We used to manually
            // set the Visible of all
            // children, but now we no
            // longer do that because there
            // is a concept of relative visibility.
            // WriteVisibleSetForNamedObjectSaves(set, entitySave);
            
            EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.After, "Visible", entitySave);
        }
Beispiel #24
0
        private static ICodeBlock GenerateCurrentStateProperty(IElement element, ICodeBlock codeBlock, string enumType, List <StateSave> states)
        {
            // early out
            if (states.Count == 0)
            {
                return(codeBlock);
            }

            string variableNameModifier = enumType;

            if (enumType == "VariableState")
            {
                variableNameModifier = "";
            }

            string qualifiedEnumType = element.Name.Replace("\\", ".").Replace("/", ".") + "." + enumType;

            string         variableToLookFor = "Current" + variableNameModifier + "State";
            CustomVariable customVariable    = element.GetCustomVariable(variableToLookFor);
            bool           hasEvent          = customVariable != null && customVariable.CreatesEvent;


            #region Header and Getter stuff - simple stuff with no logic


            codeBlock
            .Line($"private {enumType} mCurrent{variableNameModifier}State = null;");

            string publicWithOptionalNew = "public";
            if (IsStateDefinedInBase(element, enumType))
            {
                publicWithOptionalNew += " new";
            }

            // This is inclusive (-1), but includes 0 and 1 values (+2), which means the net is +1
            int maxIntValueInclusive = states.Count + 1;

            var setBlock = codeBlock
                           .Property(publicWithOptionalNew + " " + qualifiedEnumType, "Current" + variableNameModifier + "State")
                           .Get()
                           .Line(string.Format("return mCurrent{1}State;", enumType, variableNameModifier))
                           .End()
                           .Set();

            #endregion

            #region Set the state value and call an event if necessary

            bool stillNeedsToAssignValue = true;

            if (hasEvent)
            {
                EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, variableToLookFor, element);
            }

            if (stillNeedsToAssignValue)
            {
                setBlock.Line("mCurrent" + variableNameModifier + "State = value;");
            }

            #endregion

            bool isElse = false;
            foreach (StateSave stateSave in states)
            {
                GenerateVariableAssignmentForState(element, setBlock, stateSave, enumType, isElse);
                isElse = true;
            }

            if ((enumType == "VariableState" && DoesBaseHaveUncategorizedStates(element)) ||
                (!string.IsNullOrEmpty(element.BaseElement) && GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true).Any(category => category == enumType)))
            {
                setBlock.Else()
                .Line("base.Current" + variableNameModifier + "State = base.Current" + variableNameModifier + "State;");
            }

            if (hasEvent)
            {
                EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.After, variableToLookFor, element);
            }

            return(codeBlock);
        }
        private void GenerateAnimationMember(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative)
        {
            string propertyName = animation.PropertyNameInCode();
            if (absoluteOrRelative == AbsoluteOrRelative.Relative)
            {
                propertyName += "Relative";
            }
            string referencedInstructionProperty = propertyName + "Instructions";
            // Force the property to be upper-case, since the field is lower-case:



            // We want to generate something like:
            //private FlatRedBall.Gum.Animation.GumAnimation uncategorizedAnimation;
            //public FlatRedBall.Gum.Animation.GumAnimation UncategorizedAnimation
            //{
            //    get
            //    {
            //        if (uncategorizedAnimation == null)
            //        {
            //            uncategorizedAnimation = new FlatRedBall.Gum.Animation.GumAnimation(1, () => UncategorizedAnimationInstructions);
            //            uncategorizedAnimation.AddEvent("Event1", 3.0f);
            //        }
            //        return uncategorizedAnimation;
            //    }
            //}

            var firstCharacterLower = propertyName.Substring(0, 1).ToLowerInvariant();
            var fieldName = firstCharacterLower + propertyName.Substring(1);
            

            currentBlock.Line($"private FlatRedBall.Gum.Animation.GumAnimation {fieldName};");

            currentBlock = currentBlock.Property("public FlatRedBall.Gum.Animation.GumAnimation", propertyName).Get();



            float length = GetAnimationLength(context.Element, animation);

            string lengthAsString = ToFloatString(length);

            var ifBlock = currentBlock.If($"{fieldName} == null");
            {
                ifBlock.Line(
                    $"{fieldName} = new FlatRedBall.Gum.Animation.GumAnimation({lengthAsString}, () => {referencedInstructionProperty});");

                foreach(var namedEvent in animation.Events)
                {
                    string timeAsString = ToFloatString(namedEvent.Time);
                    ifBlock.Line(
                        $"{fieldName}.AddEvent(\"{namedEvent.Name}\", {timeAsString});");
                }
                foreach(var subAnimation in animation.Animations)
                {
                    if(string.IsNullOrEmpty(subAnimation.SourceObject) == false)
                    {
                        ifBlock.Line($"{fieldName}.SubAnimations.Add({subAnimation.PropertyNameInCode()});");
                    }
                }
            }

            currentBlock.Line($"return {fieldName};");
        }
        private static ICodeBlock GenerateCurrentStateProperty(IElement element, ICodeBlock codeBlock, string enumType, List<StateSave> states)
        {
            var createField = false;
            if (enumType == "VariableState" && !DoesBaseHaveUncategorizedStates(element))  //Uncategorized and not base
            {
                createField = true;
            }
            else if (enumType != "VariableState")    //Check if this state category exists in a parent entity
            {
                if (element.BaseElement != null)
                {
                    var categories = GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true);

                    if (!categories.Any(category => category == enumType))
                    {
                        createField = true;
                    }
                }else
                {
                    createField = true;
                }
            }

            string variableNameModifier = enumType;
            if (enumType == "VariableState")
            {
                variableNameModifier = "";
            }

            string qualifiedEnumType = element.Name.Replace("\\", ".").Replace("/", ".")  +  "." + enumType;

            if (states.Count != 0)
            {
                string variableToLookFor = "Current" + variableNameModifier + "State";
                CustomVariable customVariable = element.GetCustomVariable(variableToLookFor);
                bool hasEvent = customVariable != null && customVariable.CreatesEvent;


                #region Header and Getter stuff - simple stuff with no logic

                if (createField)
                {
                    codeBlock
                        .Line(string.Format("protected int mCurrent{0}State = 0;", variableNameModifier));
                }

                string publicWithOptionalNew = "public";
                if (ShouldUseNewKeyword(element, enumType))
                {
                    publicWithOptionalNew += " new";
                }
                var setBlock = codeBlock
                    .Property(publicWithOptionalNew + " " + qualifiedEnumType, "Current" + variableNameModifier + "State")
                        .Get()
                            .If(string.Format("System.Enum.IsDefined(typeof({0}), mCurrent{1}State)", enumType, variableNameModifier))
                                .Line(string.Format("return ({0})mCurrent{1}State;", enumType, variableNameModifier))
                            .End()
                            .Else()
                                .Line(string.Format("return {0}.Unknown;", enumType))
                            .End()
                        .End()
                        .Set();

                #endregion

                #region Set the state value and call an event if necessary

                bool stillNeedsToAssignValue = true;

                if (element is EntitySave)
                {
                    EntitySave asEntitySave = element as EntitySave;

                    //if (!string.IsNullOrEmpty(asEntitySave.CurrentStateChange))
                    //{
                    //    setBlock
                    //        .If("value != mCurrent" + variableNameModifier + "State")
                    //            .Line("mCurrent" + variableNameModifier + "State = value;")
                    //            .Line(asEntitySave.CurrentStateChange + "(this, null);");

                    //    stillNeedsToAssignValue = false;
                    //}
                }

                if (hasEvent)
                {
                    EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, variableToLookFor, element);
                }

                if (stillNeedsToAssignValue)
                {
                    setBlock.Line("mCurrent" + variableNameModifier + "State = (int)value;");
                }

                #endregion

                var switchBlock = setBlock.Switch("Current" + variableNameModifier + "State");

                switchBlock.Case(enumType + ".Uninitialized");
                switchBlock.Case(enumType + ".Unknown");

                foreach (StateSave stateSave in states)
                {
                    GenerateCurrentStateCodeForIndividualState(element, switchBlock, stateSave, enumType);
                }

                if ((enumType == "VariableState" && DoesBaseHaveUncategorizedStates(element)) || 
                    (!string.IsNullOrEmpty(element.BaseElement) && GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true).Any(category => category == enumType)))
                {
                    switchBlock.Default()
                        .Line("base.Current" + variableNameModifier + "State = base.Current" + variableNameModifier + "State;");
                }

                if (hasEvent)
                {
                    EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.After, variableToLookFor, element);
                }
            }
            return codeBlock;
        }
        private void GenerateEnumerableFor(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative)
        {
            string animationType = "VariableState";

            string animationName = animation.PropertyNameInCode();

            if(absoluteOrRelative == AbsoluteOrRelative.Relative)
            {
                animationName += "Relative";
            }

            string propertyName = animationName + "Instructions";

            // Instructions used to be public - the user would grab them and add them to the InstructionManager,
            // but now everything is encased in an Animation object which handles stopping itself and provides a simple
            // Play method.
            if (animation.States.Count == 0 && animation.Animations.Count == 0)
            {
                currentBlock = currentBlock.Property("private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>", propertyName).Get();

                currentBlock.Line("yield break;");

            }
            else if(absoluteOrRelative == AbsoluteOrRelative.Relative && animation.States.Count < 2 && animation.Animations.Count == 0)
            {

                currentBlock = currentBlock.Property("private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>", propertyName).Get();

                currentBlock.Line("yield break;");
            }
            else
            {
                if (animation.States.Count != 0)
                {
                    var firstState = context.Element.AllStates.FirstOrDefault(item => item.Name == animation.States.First().StateName);

                    var category = context.Element.Categories.FirstOrDefault(item => item.States.Contains(firstState));

                    if (category != null)
                    {
                        animationType = category.Name;
                    }
                }

                currentBlock = currentBlock.Property("private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>", propertyName).Get();

                GenerateOrderedStateAndSubAnimationCode(context, currentBlock, animation, animationType, absoluteOrRelative);

                if(animation.Loops)
                {
                    currentBlock = currentBlock.Block();

                    currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction(  " + 
                        "() => FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(this." + propertyName + "));");
                    string executionTime = "0.0f";

                    if(animation.States.Count != 0)
                    {
                        executionTime = ToFloatString( animation.States.Last().Time);
                    }

                    currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + executionTime + ";");

                    currentBlock.Line("yield return toReturn;");
                    currentBlock = currentBlock.End();

                }
            }
            
        }
        private static void CreateNewVariableMember(ICodeBlock codeBlock, CustomVariable customVariable, bool isExposing, IElement element)
        {
            string variableAssignment = "";

            if (customVariable.DefaultValue != null)
            {
                if (!IsTypeFromCsv(customVariable))
                {
                    variableAssignment =
                        CodeParser.ParseObjectValue(customVariable.DefaultValue);

                    // If this is a file, we don't want to assign it here
                    if (customVariable.GetIsFile())
                    {
                        variableAssignment = null;
                    }

                    if (customVariable.Type == "Color")
                    {
                        variableAssignment = "Color." + variableAssignment.Replace("\"", "");

                    }
                    else if (customVariable.Type != "string" && variableAssignment == "\"\"")
                    {
                        variableAssignment = null;
                    }

                    if (variableAssignment != null)
                    {
                        variableAssignment = " = " + variableAssignment;
                    }
                }
                else if(!string.IsNullOrEmpty(customVariable.DefaultValue as string) && (string)customVariable.DefaultValue != "<NULL>")
                {
                    // If the variable IsShared (ie static) then we
                    // don't want to assign the value because the CSV
                    // may not yet be loaded.  This may create behavior
                    // the user doesn't expect, but the alternative is either
                    // to load the file before the user wants to (which maybe we
                    // will end up doing) or to get a crash
                    // Update June 2, 2013
                    // If the customVariable 
                    // is not "IsShared" (it's
                    // not static), we don't want
                    // to assign the value where we
                    // create the variable as a field
                    // because this means the value will
                    // attempt to assign before LoadStaticContent.
                    // This can cause a crash, and has in the GlueTestProject.
                    // Update June 2, 2013
                    // Used to set it to null
                    // if it's static, but we should
                    // allow statics to set their values
                    // if they come from global content files.

                    
                    if (
                        ReferencesCsvFromGlobalContent(customVariable) &&
                        ShouldAssignToCsv(customVariable, customVariable.DefaultValue as string))
                    {
                        variableAssignment = " = " + GetAssignmentToCsvItem(customVariable, element, (string)customVariable.DefaultValue);
                    }
                    else
                    {
                        variableAssignment = null;
                    }
                }
            }

            string formatString = null;

            bool needsToBeProperty = (customVariable.SetByDerived && !customVariable.IsShared) || customVariable.CreatesProperty || customVariable.CreatesEvent
                || IsVariableWholeNumberWithVelocity(customVariable);

            needsToBeProperty = needsToBeProperty & !customVariable.GetIsVariableState();


            EventCodeGenerator.TryGenerateEventsForVariable(codeBlock, customVariable, element);
            

            string memberType = GetMemberTypeFor(customVariable, element);

            if (needsToBeProperty)
            {
                // If the variable
                // creates an event
                // then it needs to have
                // custom code (it can't be
                // an automatic property).
                bool isWholeNumberWithVelocity = IsVariableWholeNumberWithVelocity(customVariable);

                if (customVariable.CreatesEvent || isWholeNumberWithVelocity || customVariable.DefaultValue != null )
                {
                    string variableToAssignInProperty = "base." + customVariable.Name;
                    // create a field for this, unless it's defined by base - then the base creates a field for it
                    if (!isExposing && !customVariable.DefinedByBase)
                    {
                        variableToAssignInProperty = "m" + customVariable.Name;

                        // First we make the field that will get set here:
                        codeBlock.Line(StringHelper.Modifiers(Public: false, Static: customVariable.IsShared, Type: memberType, Name: variableToAssignInProperty) + variableAssignment + ";");
                    }

                    string propertyHeader = null;

                    if (isExposing)
                    {
                        propertyHeader = "public new " + memberType + " " + customVariable.Name;
                    }
                    else if (customVariable.DefinedByBase)
                    {
                        propertyHeader = "public override " + memberType + " " + customVariable.Name;
                    }
                    else if (customVariable.SetByDerived)
                    {
                        propertyHeader = "public virtual " + memberType + " " + customVariable.Name;
                    }
                    else
                    {
                        propertyHeader = "public " + memberType + " " + customVariable.Name;
                    }

                    ICodeBlock set = codeBlock.Property(propertyHeader, Static:customVariable.IsShared)
                        .Set();

                    if (EventCodeGenerator.ShouldGenerateEventsForVariable(customVariable, element))
                    {
                        EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.Before, customVariable.Name, element);
                    }

                    set.Line(variableToAssignInProperty + " = value;");
                    if (IsVariableWholeNumberWithVelocity(customVariable))
                    {
                        set.Line(customVariable.Name + "ModifiedByVelocity = value;");
                    }
                    if (EventCodeGenerator.ShouldGenerateEventsForVariable(customVariable, element))
                    {
                        EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.After, customVariable.Name, element);
                    }

                    ICodeBlock get = set.End().Get();

                    codeBlock = get.Line("return " + variableToAssignInProperty + ";")
                        .End().End(); // end the getter, end the property
                }
                else
                {
                    // Static vars can't be virtual
                    bool isVirtual = !customVariable.IsShared;
                    codeBlock.AutoProperty(customVariable.Name, Public: true, Virtual: isVirtual, Static: customVariable.IsShared, Type: memberType);
                }
            }
            else
            {
                if (!customVariable.GetIsVariableState())
                {


                    codeBlock.Line(StringHelper.Modifiers(Public: true, Static: customVariable.IsShared, Type: memberType, Name: customVariable.Name) + variableAssignment + ";");


                }
                else
                {
                    if (IsVariableTunnelingToDisabledObject(customVariable, element))
                    {
                        // If it's a varaible
                        // that is exposing a
                        // state variable for a
                        // disabled object, we still
                        // want to generate something:
                        codeBlock.Line(StringHelper.Modifiers(Public: true, Static: customVariable.IsShared, Type: memberType, Name: customVariable.Name)
                            // No assignment for now.  Do we eventually want this?  The reason
                            // this even exists is to satisfy a variable that may be needed by other
                            // code which would point to a disabled object.
                            //+ variableAssignment 
                            + ";");
                        
                    }
                }
            }
        }
Beispiel #29
0
        public void CodeGenerationStart(IElement element)
        {
            var stateChainCollection = GlueCommands.TreeNodeCommands.GetProperty <StateChainCollection>(element, PropertyName);

            if (stateChainCollection == null)
            {
                return;
            }

            var        elementNameWithoutPath = FileManager.RemovePath(element.Name);
            var        document  = new CodeDocument();
            ICodeBlock codeBlock = document;


            if (stateChainCollection.StateChains.Count <= 0)
            {
                return;
            }


            codeBlock = codeBlock
                        .Line("using FlatRedBall.Instructions;")
                        .Namespace(GlueCommands.GenerateCodeCommands.GetNamespaceForElement(element))
                        .Class("public partial ", element.ClassName, "");


            //Create Enum
            codeBlock = codeBlock
                        .Enum("public", "StateChains")
                        .Line("None = 0,");

            for (int i = 0; i < stateChainCollection.StateChains.Count; i++)
            {
                if (i == stateChainCollection.StateChains.Count - 1)
                {
                    codeBlock.Line(stateChainCollection.StateChains[i].Name);
                }
                else
                {
                    codeBlock.Line(stateChainCollection.StateChains[i].Name + ",");
                }
            }

            codeBlock = codeBlock.End();

            //Private members
            codeBlock
            ._()
            .Line("private StateChains _currentStateChain = StateChains.None;")
            .Line("private int _index;")
            .Line("private Instruction _instruction;")
            ._();

            //CurrentStateChain Property
            codeBlock = codeBlock
                        .Property("public StateChains", "CurrentStateChain")
                        .Get()
                        .Line("return _currentStateChain;")
                        .End()
                        .Set()
                        .Line("StopStateChain();")
                        ._()
                        .Line("_currentStateChain = value;")
                        .Line("_index = 0;")
                        ._()
                        .Switch("_currentStateChain");

            foreach (var stateChain in stateChainCollection.StateChains)
            {
                codeBlock
                .Case("StateChains." + stateChain.Name)
                .Line("StartNextState" + stateChain.Name + "();");
            }

            codeBlock = codeBlock
                        .End()
                        .End()
                        .End();

            codeBlock._();

            //ManageStateChains
            codeBlock = codeBlock
                        .Function("public void", "ManageStateChains", "")
                        .If("CurrentStateChain == StateChains.None")
                        .Line("return;")
                        .End()
                        ._()
                        .Switch("CurrentStateChain");

            foreach (var stateChain in stateChainCollection.StateChains)
            {
                var index = 0;

                codeBlock = codeBlock
                            .Case("StateChains." + stateChain.Name);

                foreach (var stateChainState in
                         stateChain.StateChainStates.Where(stateChainState => !string.IsNullOrEmpty(stateChainState.State)))
                {
                    if (index == 0)
                    {
                        codeBlock
                        .If("_index == 0 && CurrentState == VariableState." + stateChainState.State)
                        .Line("_index++;")
                        .Line("StartNextState" + stateChain.Name + "();");
                    }
                    else
                    {
                        codeBlock
                        .ElseIf("_index == " + index + " && CurrentState == VariableState." +
                                stateChainState.State)
                        .Line("_index++;")
                        .Line("StartNextState" + stateChain.Name + "();");
                    }

                    index++;
                }

                codeBlock = codeBlock
                            .End();
            }

            codeBlock = codeBlock
                        .End()
                        .End();

            codeBlock._();

            //StopStateChain
            codeBlock = codeBlock
                        .Function("public void", "StopStateChain", "")
                        .If("CurrentStateChain == StateChains.None")
                        .Line("return;")
                        .End()
                        ._()
                        .Switch("CurrentStateChain");

            foreach (var stateChain in stateChainCollection.StateChains)
            {
                var index = 0;

                codeBlock = codeBlock
                            .Case("StateChains." + stateChain.Name);

                foreach (var stateChainState in stateChain.StateChainStates)
                {
                    if (index == 0)
                    {
                        codeBlock
                        .If("_index == 0")
                        .Line("Instructions.Remove(_instruction);")
                        .Line("StopStateInterpolation(VariableState." + stateChainState.State + ");")
                        .End();
                    }
                    else
                    {
                        codeBlock
                        .ElseIf("_index == " + index)
                        .Line("Instructions.Remove(_instruction);")
                        .Line("StopStateInterpolation(VariableState." + stateChainState.State + ");")
                        .End();
                    }

                    index++;
                }

                codeBlock = codeBlock
                            .End();
            }

            codeBlock = codeBlock
                        .End()
                        .Line("_instruction = null;")
                        .End();

            codeBlock._();

            //StartNextState*****
            foreach (var stateChain in stateChainCollection.StateChains)
            {
                codeBlock = codeBlock
                            .Function("private void", "StartNextState" + stateChain.Name, "")
                            .If("_index < 0")
                            .Line("_index = 0;")
                            .End()
                            ._()
                            .If("_index >= " + stateChain.StateChainStates.Count)
                            .Line("_index = 0;")
                            .End()
                            ._()
                            .Switch("_index");

                var index = 0;

                foreach (var stateChainState in stateChain.StateChainStates)
                {
                    codeBlock
                    .Case(index.ToString())
                    .Line("_instruction = InterpolateToState(VariableState." + stateChainState.State + ", " + stateChainState.Time / 1000 + ");");

                    index++;
                }

                codeBlock = codeBlock
                            .End()
                            .End()
                            ._();
            }

            GlueCommands.ProjectCommands.CreateAndAddPartialFile(element, "StateChains", document.ToString());
        }
        private void GeneratePropertyForCurrentState(ICodeBlock currentBlock, string propertyType, string propertyName,
                                                     List <Gum.DataTypes.Variables.StateSave> states, ElementSave container, bool isNullable)
        {
            string propertyPrefix;

            if (isNullable)
            {
                propertyPrefix = $"public {propertyType}?";
            }
            else
            {
                propertyPrefix = $"public {propertyType}";
            }
            var property = currentBlock.Property(propertyPrefix, propertyName);

            property.Get().Line("return m" + propertyName + ";");

            var setter = property.Set();
            {
                if (isNullable)
                {
                    setter = setter.If("value != null");
                }
                setter.Line("m" + propertyName + " = value;");

                var switchBlock = setter.Switch("m" + propertyName);

                foreach (var state in states)
                {
                    var caseBlock = switchBlock.Case(propertyType + "." + state.MemberNameInCode());
                    {
                        // Parent variables need to be assigned in the order of the objects in the component so that they're attached in the right order.
                        // If they're attached in the wrong order, then stacking won't work properly:
                        var instanceNames = container.Instances.Select(item => item.Name).ToList();

                        var orderedVariables = state.Variables.OrderBy(variable => instanceNames.IndexOf(variable.SourceObject)).ToList();

                        foreach (var variable in orderedVariables)
                        {
                            var shouldGenerate = false;
                            try
                            {
                                shouldGenerate = GetIfShouldGenerateStateVariable(variable, container);
                            }
                            catch (Exception e)
                            {
                                GlueCommands.Self.PrintError(e.ToString());
                            }
                            // where block doesn't debug well for some reason, so I unrolled it...
                            if (shouldGenerate)
                            {
                                // Note that this could return values like "1,2" instead of "1.2" depending
                                // on the current language, so the AdjustVariableValueIfNecessary needs to account for that.
                                string variableValue = variable.Value.ToString();
                                bool   isEntireAssignment;

                                GueDerivingClassCodeGenerator.Self.AdjustVariableValueIfNecessary(variable, container, ref variableValue, out isEntireAssignment);
                                if (isEntireAssignment)
                                {
                                    caseBlock.Line(variableValue);
                                }
                                else
                                {
                                    string memberNameInCode = variable.MemberNameInCode(container, VariableNamesToReplaceForStates);
                                    caseBlock.Line(memberNameInCode + " = " + variableValue + ";");
                                }
                            }
                        }
                    }
                }
            }
        }
        public static void GenerateFieldAndPropertyForNamedObject(NamedObjectSave namedObjectSave, ICodeBlock codeBlock)
        {

            string typeName = GetQualifiedTypeName(namedObjectSave);

            CodeGenerationType codeGenerationType = GetFieldCodeGenerationType(namedObjectSave);

            if (codeGenerationType == CodeGenerationType.OnlyContainedObjects)
            {
                // Since the base defines it, we don't want to define the object here; however,
                // any objects that it contains will not be defined by base, so we do need to loop
                // through contained NamedObjectSaves and define those.  We also want to create variable
                // reset fields.
                CreateVariableResetField(namedObjectSave, typeName, codeBlock);

                foreach (NamedObjectSave childNos in namedObjectSave.ContainedObjects)
                {
                    GenerateFieldAndPropertyForNamedObject(childNos, codeBlock);
                }
            }

            else if(codeGenerationType == CodeGenerationType.Full)
            {
                AddIfConditionalSymbolIfNecesssary(codeBlock, namedObjectSave);

                #region Get the Access Modifier
                string accessModifier = "private";



                if (namedObjectSave.SetByDerived || namedObjectSave.ExposedInDerived)
                {
                    accessModifier = "protected";
                }

                #endregion

                string variableName = namedObjectSave.FieldName;
                codeBlock.Line(StringHelper.SpaceStrings(accessModifier, typeName, variableName) + ";");

                #region If should create public property

                bool shouldCreateProperty = namedObjectSave.HasPublicProperty || namedObjectSave.SetByContainer;

                if (shouldCreateProperty)
                {
                    var prop = codeBlock.Property(StringHelper.SpaceStrings("public", typeName),
                                                  namedObjectSave.InstanceName);
                    prop.Get()
                        .Line("return " + variableName + ";");
                    if (namedObjectSave.SetByContainer)
                    {
                        prop.Set()
                            .Line(variableName + " = value;");
                    }
                    else if (namedObjectSave.SetByDerived)
                    {
                        prop.Set("protected")
                            .Line(variableName + " = value;");
                    }
                    else
                    {
                        // This should still have a private setter to not break
                        // internal code
                        prop.Set("private")
                         .Line(variableName + " = value;");
                    }
                }
                #endregion

                CreateVariableResetField(namedObjectSave, typeName, codeBlock);

                // If this NamedObjectSave has children, then create fields for those too
                foreach (NamedObjectSave childNos in namedObjectSave.ContainedObjects)
                {
                    GenerateFieldAndPropertyForNamedObject(childNos, codeBlock);
                }
                AddEndIfIfNecessary(codeBlock, namedObjectSave);
            }
        }
Beispiel #32
0
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            if (element is EntitySave)
            {
                EntitySave entitySave = (EntitySave)element;

                if (entitySave.IsScrollableEntityList && !string.IsNullOrEmpty(entitySave.ItemType))
                {
                    string itemTypeWithoutPath = FileManager.RemovePath(entitySave.ItemType);

                    codeBlock.Line(string.Format("public System.Action<{0}> ScrollItemModified;", itemTypeWithoutPath));
                    codeBlock.Line(string.Format(
                                       "FlatRedBall.Math.PositionedObjectList<{0}> mScrollableItems = new FlatRedBall.Math.PositionedObjectList<{0}>();",
                                       itemTypeWithoutPath));

                    codeBlock.Line("FlatRedBall.PositionedObject mScrollableHandle;");
                    codeBlock.Line(string.Format("float mScrollableSpacing = {0};", entitySave.SpacingBetweenItems));
                    codeBlock.Line(string.Format("float mScrollableTopBoundary = {0};", entitySave.ListTopBound));
                    codeBlock.Line(string.Format("float mScrollableBottomBoundary = {0};", entitySave.ListBottomBound));

                    codeBlock.Line("int mScrollableFirstIndex = 0;");
                    codeBlock.Line(string.Format("{0} mLastCreatedScrollableItem;", itemTypeWithoutPath));

                    codeBlock
                    .Property("public int", "ScrollableFirstIndex")
                    .Set()
                    .Line("mScrollableFirstIndex = System.Math.Max(0, value);")

                    .If("mListShowingButUsePropertyPlease == null")
                    .While("mScrollableItems.Count > 0")
                    .Line("mScrollableItems.Last.Destroy();")
                    .End()
                    .End()

                    .Else()
                    // We add 1 because let's say the spacing is 10.  Even if the top to bottom was 1 unit, we'd see 1 item.
                    .Line("int maxShown = 1 + (int)((mScrollableTopBoundary - mScrollableBottomBoundary) / mScrollableSpacing);")
                    .Line("int maximumFirst = System.Math.Max(0, mListShowingButUsePropertyPlease.Count - maxShown);")
                    .Line("mScrollableFirstIndex = System.Math.Min(maximumFirst, mScrollableFirstIndex);")
                    .Line("mScrollableHandle.RelativeY = mScrollableFirstIndex * mScrollableSpacing + mScrollableTopBoundary;")
                    .Line("FixScrollableHandleRelativeY();")
                    .Line("int numberOfEntities = System.Math.Min(maxShown, ListShowing.Count);")

                    .While("mScrollableItems.Count > ListShowing.Count || mScrollableItems.Count > numberOfEntities")
                    .Line("mScrollableItems.Last.Destroy();")
                    .End()

                    .For("int i = 0; i < mScrollableItems.Count; i++")
                    .Line("mScrollableItems[i].RelativeY = -( i + mScrollableFirstIndex ) * mScrollableSpacing;")
                    .Line("mScrollableItems[i].ForceUpdateDependencies();")
                    .If("ScrollItemModified != null")
                    .Line("ScrollItemModified(mScrollableItems[i]);")
                    .End()
                    .End()

                    .Line("PerformScrollableItemAdditionLogic();");


                    codeBlock.Line("private System.Collections.IList mListShowingButUsePropertyPlease;");

                    codeBlock
                    .Property("public System.Collections.IList", "ListShowing")
                    .Get()
                    .Line("return mListShowingButUsePropertyPlease;")
                    .End()

                    .Set()
                    .If("value != mListShowingButUsePropertyPlease")
                    .Line("mListShowingButUsePropertyPlease = value;")
                    .Line("ScrollableFirstIndex = 0;")
                    .Line("RefreshAllScrollableListItems();");
                }
            }

            return(codeBlock);
        }
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            if (element is EntitySave)
            {
                EntitySave entitySave = (EntitySave)element;

                if (entitySave.IsScrollableEntityList && !string.IsNullOrEmpty(entitySave.ItemType))
                {
                    string itemTypeWithoutPath = FileManager.RemovePath(entitySave.ItemType);

                    codeBlock.Line(string.Format("public System.Action<{0}> ScrollItemModified;", itemTypeWithoutPath));
                    codeBlock.Line(string.Format(
                            "FlatRedBall.Math.PositionedObjectList<{0}> mScrollableItems = new FlatRedBall.Math.PositionedObjectList<{0}>();",
                            itemTypeWithoutPath));

                    codeBlock.Line("FlatRedBall.PositionedObject mScrollableHandle;");
                    codeBlock.Line(string.Format("float mScrollableSpacing = {0};", entitySave.SpacingBetweenItems));
                    codeBlock.Line(string.Format("float mScrollableTopBoundary = {0};", entitySave.ListTopBound));
                    codeBlock.Line(string.Format("float mScrollableBottomBoundary = {0};", entitySave.ListBottomBound));

                    codeBlock.Line("int mScrollableFirstIndex = 0;");
                    codeBlock.Line(string.Format("{0} mLastCreatedScrollableItem;", itemTypeWithoutPath));

                    codeBlock
                        .Property("public int", "ScrollableFirstIndex")
                            .Set()
                                .Line("mScrollableFirstIndex = System.Math.Max(0, value);")

                                .If("mListShowingButUsePropertyPlease == null")
                                    .While("mScrollableItems.Count > 0")
                                        .Line("mScrollableItems.Last.Destroy();")
                                    .End()
                                .End()

                                .Else()
                                    // We add 1 because let's say the spacing is 10.  Even if the top to bottom was 1 unit, we'd see 1 item.
                                    .Line("int maxShown = 1 + (int)((mScrollableTopBoundary - mScrollableBottomBoundary) / mScrollableSpacing);")
                                    .Line("int maximumFirst = System.Math.Max(0, mListShowingButUsePropertyPlease.Count - maxShown);")
                                    .Line("mScrollableFirstIndex = System.Math.Min(maximumFirst, mScrollableFirstIndex);")
                                    .Line("mScrollableHandle.RelativeY = mScrollableFirstIndex * mScrollableSpacing + mScrollableTopBoundary;")
                                    .Line("FixScrollableHandleRelativeY();")
                                    .Line("int numberOfEntities = System.Math.Min(maxShown, ListShowing.Count);")

                                    .While("mScrollableItems.Count > ListShowing.Count || mScrollableItems.Count > numberOfEntities")
                                        .Line("mScrollableItems.Last.Destroy();")
                                    .End()

                                    .For("int i = 0; i < mScrollableItems.Count; i++")
                                        .Line("mScrollableItems[i].RelativeY = -( i + mScrollableFirstIndex ) * mScrollableSpacing;")
                                        .Line("mScrollableItems[i].ForceUpdateDependencies();")
                                        .If("ScrollItemModified != null")
                                            .Line("ScrollItemModified(mScrollableItems[i]);")
                                        .End()
                                    .End()

                                    .Line("PerformScrollableItemAdditionLogic();");


                    codeBlock.Line("private System.Collections.IList mListShowingButUsePropertyPlease;");

                    codeBlock
                        .Property("public System.Collections.IList", "ListShowing")
                            .Get()
                                .Line("return mListShowingButUsePropertyPlease;")
                            .End()

                            .Set()
                                .If("value != mListShowingButUsePropertyPlease")
                                    .Line("mListShowingButUsePropertyPlease = value;")
                                    .Line("ScrollableFirstIndex = 0;")
                                    .Line("RefreshAllScrollableListItems();");
                }
            }

            return codeBlock;
        }
Beispiel #34
0
        private void GenerateAnimationMember(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative)
        {
            string propertyName = animation.PropertyNameInCode();

            if (absoluteOrRelative == AbsoluteOrRelative.Relative)
            {
                propertyName += "Relative";
            }
            string referencedInstructionProperty = propertyName + "Instructions";
            // Force the property to be upper-case, since the field is lower-case:



            // We want to generate something like:
            //private FlatRedBall.Gum.Animation.GumAnimation uncategorizedAnimation;
            //public FlatRedBall.Gum.Animation.GumAnimation UncategorizedAnimation
            //{
            //    get
            //    {
            //        if (uncategorizedAnimation == null)
            //        {
            //            uncategorizedAnimation = new FlatRedBall.Gum.Animation.GumAnimation(1, () => UncategorizedAnimationInstructions);
            //            uncategorizedAnimation.AddEvent("Event1", 3.0f);
            //        }
            //        return uncategorizedAnimation;
            //    }
            //}

            var firstCharacterLower = propertyName.Substring(0, 1).ToLowerInvariant();
            var fieldName           = firstCharacterLower + propertyName.Substring(1);


            currentBlock.Line($"private FlatRedBall.Gum.Animation.GumAnimation {fieldName};");

            currentBlock = currentBlock.Property("public FlatRedBall.Gum.Animation.GumAnimation", propertyName).Get();



            float length = GetAnimationLength(context.Element, animation);

            string lengthAsString = ToFloatString(length);

            var ifBlock = currentBlock.If($"{fieldName} == null");

            {
                ifBlock.Line(
                    $"{fieldName} = new FlatRedBall.Gum.Animation.GumAnimation({lengthAsString}, {referencedInstructionProperty});");

                foreach (var namedEvent in animation.Events)
                {
                    string timeAsString = ToFloatString(namedEvent.Time);
                    ifBlock.Line(
                        $"{fieldName}.AddEvent(\"{namedEvent.Name}\", {timeAsString});");
                }
                foreach (var subAnimation in animation.Animations)
                {
                    if (string.IsNullOrEmpty(subAnimation.SourceObject) == false)
                    {
                        var isMissingInstance = context.Element.GetInstance(subAnimation.SourceObject) == null;
                        if (isMissingInstance)
                        {
                            ifBlock.Line($"//Missing object {subAnimation.SourceObject}");
                        }
                        else
                        {
                            ifBlock.Line($"{fieldName}.SubAnimations.Add({subAnimation.PropertyNameInCode()});");
                        }
                    }
                }
            }

            currentBlock.Line($"return {fieldName};");
        }
        private static void AppendPropertyForReferencedFileSave(ICodeBlock codeBlock, ReferencedFileSave referencedFile, string containerName, IElement element, string contentManagerName, AssetTypeInfo ati, string variableName, string typeName)
        {

            codeBlock.Line(StringHelper.Modifiers(Static: referencedFile.IsSharedStatic, Type: typeName, Name: "m" + variableName) + ";");

            // No need to use
            // ManualResetEvents
            // if the ReferencedFileSave
            // is LoadedOnlyWhenReferenced.

            bool shouldBlockThreads = containerName ==
                ContentLoadWriter.GlobalContentContainerName && !referencedFile.LoadedOnlyWhenReferenced;

            if (shouldBlockThreads)
            {
                codeBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING");

                codeBlock.Line("//Blocks the thread on request of " + variableName + " until it has been loaded");
                codeBlock.Line("static ManualResetEvent m" + variableName + "Mre = new ManualResetEvent(false);");

                codeBlock.Line("// Used to lock getter and setter so that " + variableName + " can be set on any thread even if its load is in progrss");
                codeBlock.Line("static object m" + variableName + "_Lock = new object();");
                codeBlock.Line("#endif");

            }

            string lastContentManagerVariableName = "mLastContentManagerFor" + variableName;
            if (referencedFile.LoadedAtRuntime && element != null)
            {
                codeBlock.Line("static string " + lastContentManagerVariableName + ";");
            }

            // Silverlight and Windows Phone only allow reflection on public methods
            // Since it's common practice to use reflection to reference LoadedOnlyWhenReferenced
            // properties, we need to make them public.
            var propBlock = codeBlock.Property(variableName, Public: true, Static: referencedFile.IsSharedStatic, Type: typeName);

            var getBlock = propBlock.Get();

            if (referencedFile.LoadedOnlyWhenReferenced)
            {
                WriteLoadedOnlyWhenReferencedPropertyBody(referencedFile, containerName, element, contentManagerName, ati, variableName, lastContentManagerVariableName, getBlock);
            }
            else if (containerName == ContentLoadWriter.GlobalContentContainerName)
            {
                #region Write the getter


                getBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING");

                if (shouldBlockThreads)
                {
                    getBlock = getBlock.Lock("m" + variableName + "_Lock");
                }

                //Perform a WaitOne on the event with a timeout value of zero.
                // It will return true if the event is not set, or false if the timeout occurs. 
                // In other words, false -> event is set, true -> event is not set.
                getBlock.Line("bool isBlocking = !m" + variableName + "Mre.WaitOne(0);");

                {
                    var ifBlock = getBlock.If("isBlocking");

                    // This is our way of telling the GlobalContentManager to hurry up - we're waiting
                    // on some content!
                    ifBlock.Line("RequestContentLoad(\"" + referencedFile.Name + "\");");

                    #region If RecordLockRecord - write the code for recording the load order so that it can be optimized

                    if (ProjectManager.GlueProjectSave.GlobalContentSettingsSave.RecordLockContention)
                    {
                        ifBlock.Line("LockRecord.Add(\"\\n" + variableName + "\");");
                    }

                    #endregion
                }

                getBlock.Line("m" + variableName + "Mre.WaitOne();");
                getBlock.Line("return m" + variableName + ";");
                if (shouldBlockThreads)
                {
                    getBlock = getBlock.End();
                }
                getBlock.Line("#else");
                WriteLoadedOnlyWhenReferencedPropertyBody(referencedFile, containerName, element, contentManagerName, ati, variableName, lastContentManagerVariableName, getBlock);


                getBlock.Line("#endif");

                #endregion

                #region Write the setter



                var setBlock = propBlock.Set();

                setBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING");

                if (shouldBlockThreads)
                {
                    setBlock = setBlock.Lock("m" + variableName + "_Lock");
                }

                WriteAssignmentAndMreSet(variableName, setBlock);
                if (shouldBlockThreads)
                {
                    setBlock = setBlock.End();
                }
                setBlock.Line("#else");
                setBlock.Line("m" + variableName + " = value;");


                setBlock.Line("#endif");
                #endregion

            }
            else
            {
                string fieldName = "m" + variableName;

                getBlock.Line("#if REQUIRES_PRIMARY_THREAD_LOADING");
                
                var ifBlock = getBlock.If("fieldName == null && FlatRedBall.FlatRedBallServices.IsThreadPrimary()");
                ifBlock.Line("FlatRedBall.FlatRedBallServices.GetContentManagerByName(ContentManager).ProcessTexturesWaitingToBeLoaded();");
                
                getBlock.Line("#endif");

                getBlock.Line("return " + fieldName + ";");
            }
        }
Beispiel #36
0
        public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element)
        {
            ///////////////Early Out//////////////////////
            if (GetIfIsPlatformer(element) == false)
            {
                return(codeBlock);
            }
            /////////////End Early Out////////////////////



            codeBlock.Line("#region Platformer Fields");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// See property for information.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("bool mIsOnGround = false;");

            codeBlock.Line("bool wasOnGroundLastFrame = false;");

            codeBlock.Line("private float lastNonZeroPlatformerHorizontalMaxSpeed = 0;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Whether the character has hit its head on a solid");
            codeBlock.Line("/// collision this frame. This typically occurs when the");
            codeBlock.Line("/// character is moving up in the air. It is used to prevent");
            codeBlock.Line("/// upward velocity from being applied while the player is");
            codeBlock.Line("/// holding down the jump button.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("bool mHitHead = false;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The current slope that the character is standing or walking on in degrees relative");
            codeBlock.Line("/// to the direction that the character is facing. In other words, if the charater is");
            codeBlock.Line("/// walking uphill to the right (positive slope), if the character turns around the value");
            codeBlock.Line("/// will be negative.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("float currentSlope = 0;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Whether the character is in the air and has double-jumped.");
            codeBlock.Line("/// This is used to determine which movement variables are active,");
            codeBlock.Line("/// effectively preventing multiple double-jumps.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("bool mHasDoubleJumped = false;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The time when the jump button was last pushed. This is used to");
            codeBlock.Line("/// determine if upward velocity should be applied while the user");
            codeBlock.Line("/// holds the jump button down.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("double mTimeJumpPushed = double.NegativeInfinity;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The MovementValues which were active when the user last jumped.");
            codeBlock.Line("/// These are used to determine the upward velocity to apply while");
            codeBlock.Line("/// the user holds the jump button.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("DataTypes.PlatformerValues mValuesJumpedWith;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// See property for information.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("DataTypes.PlatformerValues mCurrentMovement;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// See property for information.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("HorizontalDirection mDirectionFacing;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// See property for information.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("MovementType mMovementType;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The last time collision checks were performed. Time values uniquely");
            codeBlock.Line("/// identify a game frame, so this is used to store whether collisions have");
            codeBlock.Line("/// been tested this frame or not. This is used to determine whether collision");
            codeBlock.Line("/// variables should be reset or not when a collision method is called, as");
            codeBlock.Line("/// multiple collisions (such as vs. solid and vs. cloud) may occur in one frame.");
            codeBlock.Line("/// </summary>");
            codeBlock.Line("double mLastCollisionTime = -1;");
            codeBlock.Line("#endregion");



            codeBlock.Line("#region Platformer Properties");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Returns the current time, considering whether a Screen is active. ");
            codeBlock.Line("/// This is used to control how long a user can hold the jump button during");
            codeBlock.Line("/// a jump to apply upward velocity.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("double", "CurrentTime")
            .Get()
            .If("FlatRedBall.Screens.ScreenManager.CurrentScreen != null")
            .Line("return FlatRedBall.Screens.ScreenManager.CurrentScreen.PauseAdjustedCurrentTime;")
            .End()
            .Else()
            .Line("return FlatRedBall.TimeManager.CurrentTime;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The current movement variables used for horizontal movement and jumping.");
            codeBlock.Line("/// These automatically get set according to the default platformer logic and should");
            codeBlock.Line("/// not be manually adjusted.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("protected DataTypes.PlatformerValues", "CurrentMovement")
            .Get()
            .Line("return mCurrentMovement;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Which direciton the character is facing.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("protected HorizontalDirection", "DirectionFacing")
            .Get()
            .Line("return mDirectionFacing;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The input object which controls whether the jump was pressed.");
            codeBlock.Line("/// Common examples include a button or keyboard key.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public FlatRedBall.Input.IPressableInput", "JumpInput");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The input object which controls the horizontal movement of the character.");
            codeBlock.Line("/// Common examples include a d-pad, analog stick, or keyboard keys.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public FlatRedBall.Input.I1DInput", "HorizontalInput");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The input object which controls vertical input such as moving on ladders or falling through cloud collision.");
            codeBlock.Line("/// -1 represents full down, 0 is neutral, +1 is full up.");

            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public FlatRedBall.Input.I1DInput", "VerticalInput");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The ratio that the horizontal input is being held.");
            codeBlock.Line("/// -1 represents full left, 0 is neutral, +1 is full right.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("protected virtual float", "HorizontalRatio")
            .Get()
            .If("!InputEnabled")
            .Line("return 0;")
            .End()
            .Else()
            .Line("return HorizontalInput.Value;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Whether the character is on the ground. This is false");
            codeBlock.Line("/// if the character has jumped or walked off of the edge");
            codeBlock.Line("/// of a platform.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("public bool", "IsOnGround")
            .Get()
            .Line("return mIsOnGround;");



            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// The current movement type. This is set by the default platformer logic and");
            codeBlock.Line("/// is used to assign the mCurrentMovement variable.");
            codeBlock.Line("/// </summary>");
            codeBlock.Property("public MovementType", "CurrentMovementType")
            .Get()
            .Line("return mMovementType;")
            .End()
            .Set()
            .Line("mMovementType = value;")
            .Line("UpdateCurrentMovement();")

            .If("CurrentMovement != null")
            .Line("this.YAcceleration = -CurrentMovement.Gravity;");

            codeBlock.Line("/// <summary>");
            codeBlock.Line("/// Whether input is read to control the movement of the character.");
            codeBlock.Line("/// This can be turned off if the player should not be able to control");
            codeBlock.Line("/// the character.");
            codeBlock.Line("/// </summary>");
            codeBlock.AutoProperty("public bool", "InputEnabled");



            // This can be used to add anything else here without the complexity of CodeBlock calls
            codeBlock.Line(
                @"

            /// <summary>
            /// Stores the value that the entity must fall down to before cloud collision is enabled.
            /// If this value is null, then cloud collision is enabled. When the entity falls through a
            /// cloud (by pressing down direction + jump), then this value is set. 
            /// </summary>
            private float? cloudCollisionFallThroughY = null;
");



            codeBlock.Line("#endregion");

            codeBlock.Line(
                @"
        /// <summary>
        /// Action for when the character executes a jump.
        /// </summary>
        public System.Action JumpAction;

        /// <summary>
        /// Action for when the character lands from a jump.
        /// </summary>
        public System.Action LandedAction;

");
            return(codeBlock);
        }
        private static ICodeBlock WritePropertyHeader(ICodeBlock codeBlock, CustomVariable customVariable, string customVariableType)
        {
            ICodeBlock prop;

            bool needsToCloseIf = false;

            if (customVariableType == "Microsoft.Xna.Framework.Color")
            {
                codeBlock.Line("#if XNA3 || SILVERLIGHT");
                prop = codeBlock.Property(customVariable.Name, Public: true,
                                         Override: customVariable.DefinedByBase,
                                         Virtual: (customVariable.SetByDerived && !customVariable.IsShared),
                                         Type: "Microsoft.Xna.Framework.Graphics.Color");
                prop.PreCodeLines.RemoveAt(1); // get rid of its opening bracket
                prop.PostCodeLines.Clear();
                prop.End();
                codeBlock.Line("#else");
                needsToCloseIf = true;
            }


            prop = codeBlock.Property(customVariable.Name, Public: true,
                                     Override: customVariable.DefinedByBase,
                                     Virtual: (customVariable.SetByDerived && !customVariable.IsShared),
                                     Type: customVariableType);
            if (needsToCloseIf)
            {
                prop.PreCodeLines.Insert(1, new CodeLine("#endif"));
            }
            return prop;
        }