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); }
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 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;"); } }
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)); } }
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); }
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; */ }
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 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 + ";"); } } } }
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); } }
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; }
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 + ";"); } }
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; }