private static ICodeBlock SetInterpolateBetweenValuesForStates(IElement element, string enumType, List <StateSave> states, ICodeBlock curBlock, Dictionary <InstructionSave, InterpolationCharacteristic> mInterpolationCharacteristics, string firstOrSecondValue) { foreach (StateSave state in states) { curBlock = curBlock.Case(enumType + "." + state.Name); foreach (InstructionSave instructionSave in state.InstructionSaves) { var customVariable = element.GetCustomVariable(instructionSave.Member); NamedObjectSave sourceNamedObjectSave = null; if (customVariable != null) { sourceNamedObjectSave = element.GetNamedObjectRecursively(customVariable.SourceObject); } if (sourceNamedObjectSave != null) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(curBlock, sourceNamedObjectSave); } if (GetValue(mInterpolationCharacteristics, instructionSave.Member) != InterpolationCharacteristic.CantInterpolate) { if (instructionSave.Value == null) { curBlock.Line("set" + instructionSave.Member + " = false;"); } else { string valueToWrite = GetRightSideAssignmentValueAsString(element, instructionSave); curBlock.Line(instructionSave.Member + firstOrSecondValue + " = " + valueToWrite + ";"); } } else // This value can't be interpolated, but if the user has set a value of 0 or 1, then it should be set { ICodeBlock ifBlock; // value will come from the first state unless the interpolationValue is 1. // This makes the code behave the same as InterpolateTo which uses instructions. if (firstOrSecondValue == FirstValue) { ifBlock = curBlock.If("interpolationValue < 1"); } else { ifBlock = curBlock.If("interpolationValue >= 1"); } string valueToWrite = GetRightSideAssignmentValueAsString(element, instructionSave); ifBlock.Line("this." + instructionSave.Member + " = " + valueToWrite + ";"); } if (sourceNamedObjectSave != null) { NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(curBlock, sourceNamedObjectSave); } } curBlock = curBlock.End(); } return(curBlock); }
private static ICodeBlock AssignValuesUsingStartingValues(IElement element, ICodeBlock curBlock, Dictionary <InstructionSave, InterpolationCharacteristic> mInterpolationCharacteristics) { foreach (KeyValuePair <InstructionSave, InterpolationCharacteristic> kvp in mInterpolationCharacteristics) { if (kvp.Value != InterpolationCharacteristic.CantInterpolate) { curBlock = curBlock.If("set" + kvp.Key.Member); CustomVariable variable = element.GetCustomVariable(kvp.Key.Member); var nos = element.GetNamedObjectRecursively(variable.SourceObject); if (nos != null) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(curBlock, nos); } string relativeValue = InstructionManager.GetRelativeForAbsolute(kvp.Key.Member); string variableToAssign = kvp.Key.Member; string leftSideOfEqualsWithRelative = GetLeftSideOfEquals(element, variable, kvp.Key, true); if (!string.IsNullOrEmpty(leftSideOfEqualsWithRelative) && leftSideOfEqualsWithRelative != kvp.Key.Member) { string beforeDotParent = variable.SourceObject; if (string.IsNullOrEmpty(variable.SourceObject)) { beforeDotParent = "this"; } curBlock = curBlock.If(beforeDotParent + ".Parent != null"); AddAssignmentForInterpolationForVariable(curBlock, variable, variableToAssign, leftSideOfEqualsWithRelative); curBlock = curBlock.End().Else(); } AddAssignmentForInterpolationForVariable(curBlock, variable, variableToAssign, variableToAssign); if (!string.IsNullOrEmpty(relativeValue)) { curBlock = curBlock.End(); // end the else } curBlock = curBlock.End(); if (nos != null) { NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(curBlock, nos); } } } return(curBlock); }
private static ICodeBlock GetCreateNewFactoryMethod(ICodeBlock codeBlock, string className, bool poolObjects, string baseEntityName) { className = className.Substring(0, className.Length - "Factory".Length); // no tabs needed on first line codeBlock .Function(StringHelper.SpaceStrings("public", "static", className), "CreateNew", "float x = 0, float y = 0") .Line("return CreateNew(null, x, y);") .End(); codeBlock = codeBlock .Function(StringHelper.SpaceStrings("public", "static", className), "CreateNew", "Layer layer, float x = 0, float y = 0"); codeBlock.Line(className + " instance = null;"); if (poolObjects) { // only throw exception if pooled. This requires the user to pool the factory. // But do we want to have an explicit "IsInitialized" value? Maybe if this causes problems in the future... codeBlock.If("string.IsNullOrEmpty(mContentManagerName)") .Line("throw new System.Exception(\"You must first initialize the factory for this type because it is pooled. You can either add PositionedObjectList of type " + className + " (the most common solution) or call Initialize in custom code\");") .End(); codeBlock .Line("instance = mPool.GetNextAvailable();") .If("instance == null") .Line("mPool.AddToPool(new " + className + "(mContentManagerName, false));") .Line("instance = mPool.GetNextAvailable();") .End() .Line("instance.AddToManagers(layer);"); } else { // If not pooled don't require a content manager, can use the current screen's, so that init isn't required: //instance = new FactoryEntityWithNoList(mContentManagerName ?? FlatRedBall.Screens.ScreenManager.CurrentScreen.ContentManagerName, false); codeBlock .Line($"instance = new {className}(mContentManagerName ?? FlatRedBall.Screens.ScreenManager.CurrentScreen.ContentManagerName, false);") .Line("instance.AddToManagers(layer);"); } codeBlock.Line("instance.X = x;"); codeBlock.Line("instance.Y = y;"); CreateAddToListCode(codeBlock, className); codeBlock = codeBlock .If("EntitySpawned != null") .Line("EntitySpawned(instance);") .End() .Line("return instance;") .End(); return(codeBlock); }
private void GenerateEntitySaveUpdateDependencies(ICodeBlock codeBlock, IElement element) { EntityManagementValues managementValues = Values?.EntityManagementValueList?.FirstOrDefault(item => item.Name == element.Name); if (managementValues != null) { var innerCodeBlock = new CodeBlockBase(null); GenerateEntityUpdateDependencies(innerCodeBlock, element, managementValues); GenerateNamedObjectUpdateDependencies(innerCodeBlock, element, managementValues); var doAnyNamedObjectsHaveUpdateDependencies = innerCodeBlock.BodyCodeLines.Any(); if (doAnyNamedObjectsHaveUpdateDependencies) { var ifBlock = codeBlock.If("this.LastDependencyUpdate != currentTime"); // todo - need to call base here if we actually want to update dependencies var shouldCallBase = managementValues.PropertyManagementMode == Enums.PropertyManagementMode.FullyManaged || managementValues.SelectedProperties.Contains("Attachment"); if (shouldCallBase) { ifBlock.Line("base.UpdateDependencies(currentTime);"); } ifBlock.Line("this.mLastDependencyUpdate = currentTime;"); ifBlock.InsertBlock(innerCodeBlock); } } }
private ICodeBlock GenerateInterpolateToStateAdvanced(ICodeBlock codeBlock, string enumName) { codeBlock = codeBlock.Function("public void", "InterpolateToState", enumName + " fromState, " + enumName + " toState, double secondsToTake, FlatRedBall.Glue.StateInterpolation.InterpolationType interpolationType, FlatRedBall.Glue.StateInterpolation.Easing easing"); string variableName; if (enumName == "VariableState") { variableName = "CurrentState"; } else { variableName = "Current" + enumName + "State"; } codeBlock = codeBlock.If("secondsToTake <= 0"); codeBlock.Line(variableName + " = toState;"); codeBlock = codeBlock.End().Else(); // Immediately set the state to the from state: codeBlock.Line(variableName + " = fromState;"); codeBlock.Line("mFrom" + enumName + "Tween = fromState;"); codeBlock.Line("mTo" + enumName + "Tween = toState;"); codeBlock.Line( TweenerNameFor(enumName) + ".Start(0, 1, (float)secondsToTake, FlatRedBall.Glue.StateInterpolation.Tweener.GetInterpolationFunction(interpolationType, easing));"); codeBlock = codeBlock.End();// else codeBlock = codeBlock.End(); return(codeBlock); }
public override ICodeBlock GenerateInitialize(ICodeBlock codeBlock, IElement element) { /////////////////Early Out////////////////////// if (TopDownEntityPropertyLogic.GetIfIsTopDown(element) == false) { return(codeBlock); } //////////////End Early Out////////////////////// // The platformer plugin sets events here, but we don't need to // here on the top-down (yet) since there are no events // Update 1 - actually we should prob assign the default movement // here if there is one... codeBlock.Line("InitializeInput();"); var ifBlock = codeBlock.If("TopDownValues?.Count > 0"); { ifBlock.Line("mCurrentMovement = TopDownValues.Values.FirstOrDefault();"); } codeBlock.Line("PossibleDirections = PossibleDirections.FourWay;"); codeBlock.Line("mTopDownAnimationLayer = new TopDown.DirectionBasedAnimationLayer();"); codeBlock.Line("mTopDownAnimationLayer.TopDownEntity = this;"); return(codeBlock); }
private void GenerateApplyStateOverride(ElementSave elementSave, ICodeBlock currentBlock) { currentBlock = currentBlock.Function("public override void", "ApplyState", "Gum.DataTypes.Variables.StateSave state"); { currentBlock.Line("bool matches = this.ElementSave.AllStates.Contains(state);"); var ifStatement = currentBlock.If("matches"); { ifStatement.Line("var category = this.ElementSave.Categories.FirstOrDefault(item => item.States.Contains(state));"); var innerIf = ifStatement.If("category == null"); { foreach (var state in elementSave.States) { innerIf.Line($"if (state.Name == \"{state.Name}\") this.mCurrentVariableState = VariableState.{state.MemberNameInCode()};"); } } foreach (var category in elementSave.Categories) { var elseIf = ifStatement.ElseIf($"category.Name == \"{category.Name}\""); { foreach (var state in category.States) { elseIf.Line($"if(state.Name == \"{state.Name}\") this.mCurrent{category.Name}State = {category.Name}.{state.MemberNameInCode()};"); } } } } currentBlock.Line("base.ApplyState(state);"); } }
private void GenerateInterpolateTo(ElementSave elementSave, ICodeBlock codeBlock, IEnumerable <StateSave> states, string enumName) { string qualifiedEnum = GueDerivingClassCodeGenerator.GueRuntimeNamespace + "." + FlatRedBall.IO.FileManager.RemovePath(elementSave.Name) + "Runtime." + enumName; // Make this thing return the Tweener so the uer can customize it string parameters = qualifiedEnum + " fromState," + qualifiedEnum + " toState, double secondsToTake, " + "FlatRedBall.Glue.StateInterpolation.InterpolationType interpolationType, FlatRedBall.Glue.StateInterpolation.Easing easing, object owner = null"; codeBlock = codeBlock.Function("public FlatRedBall.Glue.StateInterpolation.Tweener", "InterpolateTo", parameters); { codeBlock.Line("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from:0, to:1, duration:(float)secondsToTake, type:interpolationType, easing:easing );"); codeBlock.If("owner == null") .Line("tweener.Owner = this;") .End() .Else() .Line("tweener.Owner = owner;"); codeBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(fromState, toState, newPosition);"); codeBlock.Line("tweener.Start();"); codeBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); codeBlock.Line("return tweener;"); } }
private static ICodeBlock CreateAddToListIfNotNullCode(ICodeBlock codeBlock, string listName) { codeBlock .If(listName + " != null") .Line(listName + ".Add(instance);") .End(); return(codeBlock); }
private void GenerateInterpolateToFromCurrent(ICodeBlock currentBlock, string enumType, bool isRelative) { string functionName = "InterpolateTo"; string whereToLook = "States"; if (enumType != "VariableState") { whereToLook = $"Categories.First(item => item.Name == \"{enumType}\").States"; } string toStateRightSide = $"this.ElementSave.{whereToLook}.First(item => item.Name == toState.ToString());"; if (isRelative) { functionName = "InterpolateToRelative"; toStateRightSide = "AddToCurrentValuesWithState(toState);"; } currentBlock = currentBlock.Function("public FlatRedBall.Glue.StateInterpolation.Tweener", functionName, enumType + " toState, double secondsToTake, FlatRedBall.Glue.StateInterpolation.InterpolationType interpolationType, FlatRedBall.Glue.StateInterpolation.Easing easing, object owner = null "); currentBlock.Line("Gum.DataTypes.Variables.StateSave current = GetCurrentValuesOnState(toState);"); currentBlock.Line("Gum.DataTypes.Variables.StateSave toAsStateSave = " + toStateRightSide); currentBlock.Line("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from: 0, to: 1, duration: (float)secondsToTake, type: interpolationType, easing: easing);"); currentBlock.If("owner == null") .Line("tweener.Owner = this;") .End() .Else() .Line("tweener.Owner = owner;"); currentBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(current, toAsStateSave, newPosition);"); string variableName; if (enumType == "VariableState") { variableName = "CurrentVariableState"; } else { variableName = $"Current{enumType}State"; } currentBlock.Line($"tweener.Ended += ()=> this.{variableName} = toState;"); currentBlock.Line("tweener.Start();"); currentBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); currentBlock.Line("return tweener;"); }
private static void GenerateDebugCheckForInterpolationValueNaN(ICodeBlock codeBlock) { codeBlock.Line("#if DEBUG"); codeBlock.If("float.IsNaN(interpolationValue)") .Line("throw new System.Exception(\"interpolationValue cannot be NaN\");") .End(); codeBlock.Line("#endif"); }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, IElement element) { bool shouldGenerate = GetIfShouldGenerate(element); if (shouldGenerate) { var ifBlock = codeBlock.If("CurrentTileMap != null"); ifBlock.Line("CurrentTileMap.AnimateSelf();"); } return(codeBlock); }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, IElement element) { bool shouldGenerate = GetIfShouldGenerate(element); if (shouldGenerate) { var ifBlock = codeBlock.If("CurrentTileMap != null"); ifBlock.Line("CurrentTileMap.AnimateSelf();"); } return codeBlock; }
public override ICodeBlock GenerateDestroy(ICodeBlock codeBlock, IElement element) { // This needs to be before the base.Destroy(); call so that the derived class can make itself unused before the base class get a chance if (element is EntitySave && (element as EntitySave).CreatedByOtherEntities) { codeBlock .If("Used") .Line(string.Format("Factories.{0}Factory.MakeUnused(this, false);", FileManager.RemovePath(element.Name))); } return(codeBlock); }
private static ICodeBlock GetCreateNewFactoryMethod(ICodeBlock codeBlock, string className, bool poolObjects, string baseEntityName) { className = className.Substring(0, className.Length - "Factory".Length); // no tabs needed on first line codeBlock .Function(StringHelper.SpaceStrings("public", "static", className), "CreateNew", "") .Line("return CreateNew(null);") .End(); codeBlock = codeBlock .Function(StringHelper.SpaceStrings("public", "static", className), "CreateNew", "Layer layer") .If("string.IsNullOrEmpty(mContentManagerName)") .Line("throw new System.Exception(\"You must first initialize the factory to use it. You can either add PositionedObjectList of type " + className + " (the most common solution) or call Initialize in custom code\");") .End() .Line(className + " instance = null;"); if (poolObjects) { codeBlock .Line("instance = mPool.GetNextAvailable();") .If("instance == null") .Line("mPool.AddToPool(new " + className + "(mContentManagerName, false));") .Line("instance = mPool.GetNextAvailable();") .End() .Line("instance.AddToManagers(layer);"); } else { codeBlock .Line(string.Format("instance = new {0}(mContentManagerName, false);", className)) .Line("instance.AddToManagers(layer);"); } CreateAddToListIfNotNullCode(codeBlock, "mScreenListReference"); if (!string.IsNullOrEmpty(baseEntityName)) { CreateAddToListIfNotNullCode(codeBlock, "mBaseScreenListReference"); } codeBlock = codeBlock .If("EntitySpawned != null") .Line("EntitySpawned(instance);") .End() .Line("return instance;") .End(); return(codeBlock); }
private void GeneratePauseForNos(NamedObjectSave nos, ICodeBlock codeBlock) { // eventually I may want to move this to AssetTypeInfo.... if (nos.InstanceType == "SoundEffectInstance") { var instanceName = nos.InstanceName; var ifBlock = codeBlock.If(instanceName + ".State == Microsoft.Xna.Framework.Audio.SoundState.Playing"); { ifBlock.Line(instanceName + ".Pause();"); ifBlock.Line("instructions.Add(new FlatRedBall.Instructions.DelegateInstruction(() => " + instanceName + ".Resume()));"); } ifBlock.End(); } }
public override ICodeBlock GenerateActivity(ICodeBlock codeBlock, IElement element) { foreach (EventResponseSave ers in element.Events) { if ((ers.GetEventSave() != null && !string.IsNullOrEmpty(ers.GetEventSave().ConditionCode))) { codeBlock = codeBlock.If(ers.GetEventSave().ConditionCode + " && " + ers.EventName + " != null"); codeBlock.Line(ers.EventName + "();"); codeBlock = codeBlock.End(); } } return(codeBlock); }
private static void AddSetResolutionCode(ICodeBlock methodContents) { if (ProjectManager.GlueProjectSave.SetResolution) { bool pcOnlySetResolution = ProjectManager.GlueProjectSave.ApplyToFixedResolutionPlatforms == false; methodContents.Line("#if WINDOWS"); if (ProjectManager.GlueProjectSave.RunFullscreen) { methodContents.Line("FlatRedBall.FlatRedBallServices.GraphicsOptions.SetFullScreen(width, height);"); } else { methodContents.Line("FlatRedBall.FlatRedBallServices.GraphicsOptions.SetResolution(width, height);"); } methodContents.Line("#elif IOS || ANDROID"); // We used to not set the resolution on iOS/Android, but this makes the camera not use the full screen. // We want it to do that, so we'll do this: // Update November 12, 2015 // Setting everything to fullscreen makes things render correctly, and also // hides the status UI on iOS, but we also need to set the resolution to the // native resolution for the cursor to work correctly: //methodContents.Line("FlatRedBall.FlatRedBallServices.GraphicsOptions.SetFullScreen(width, height);"); methodContents.Line( //"FlatRedBall.FlatRedBallServices.GraphicsOptions.SetFullScreen(width, height);" "FlatRedBall.FlatRedBallServices.GraphicsOptions.SetFullScreen(FlatRedBall.FlatRedBallServices.GraphicsOptions.ResolutionWidth, FlatRedBall.FlatRedBallServices.GraphicsOptions.ResolutionHeight);" ); // closes the #if platform section methodContents.Line("#endif"); methodContents.Line("#if WINDOWS_PHONE || WINDOWS_8 || IOS || ANDROID"); var ifBlock = methodContents.If("height > width"); { ifBlock.Line("graphicsDeviceManager.SupportedOrientations = DisplayOrientation.Portrait;"); } var elseBlock = ifBlock.End().Else(); { elseBlock.Line("graphicsDeviceManager.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;"); } methodContents.Line("#endif"); } }
private void GenerateInterpolateBetween(ElementSave elementSave, ICodeBlock currentBlock, string enumType, IEnumerable<StateSave> states) { // We used to only generate these if there was were any states in this category, but // since Gum generated code supports dynamic states, there could be states in a category // even if they're not defined in Gum. //if (states.Count() > 0) { currentBlock = currentBlock.Function("public void", "InterpolateBetween", enumType + " firstState, " + enumType + " secondState, float interpolationValue"); GenerateDebugCheckForInterpolationValueNaN(currentBlock); Dictionary<VariableSave, InterpolationCharacteristic> interpolationCharacteristics = new Dictionary<VariableSave, InterpolationCharacteristic>(); CreateStartingValueVariables(elementSave, states, currentBlock, interpolationCharacteristics); currentBlock = currentBlock.Switch("firstState"); currentBlock = SetInterpolateBetweenValuesForStates(elementSave, enumType, states, currentBlock, interpolationCharacteristics, FirstValue); currentBlock = currentBlock.End(); currentBlock = currentBlock.Switch("secondState"); currentBlock = SetInterpolateBetweenValuesForStates(elementSave, enumType, states, currentBlock, interpolationCharacteristics, SecondValue); currentBlock = currentBlock.End(); currentBlock = AssignValuesUsingStartingValues(elementSave, currentBlock, interpolationCharacteristics); currentBlock = currentBlock.If("interpolationValue < 1"); string fieldToAssign; if (enumType == "VariableState") { fieldToAssign = "mCurrentVariableState"; } else { fieldToAssign = "mCurrent" + enumType + "State"; } currentBlock.Line(fieldToAssign + " = firstState;"); currentBlock = currentBlock.End().Else(); currentBlock.Line(fieldToAssign + " = secondState;"); currentBlock = currentBlock.End(); } }
private void GenerateInterpolateBetween(ElementSave elementSave, ICodeBlock currentBlock, string enumType, IEnumerable <StateSave> states) { // We used to only generate these if there was were any states in this category, but // since Gum generated code supports dynamic states, there could be states in a category // even if they're not defined in Gum. //if (states.Count() > 0) { currentBlock = currentBlock.Function("public void", "InterpolateBetween", enumType + " firstState, " + enumType + " secondState, float interpolationValue"); GenerateDebugCheckForInterpolationValueNaN(currentBlock); Dictionary <VariableSave, InterpolationCharacteristic> interpolationCharacteristics = new Dictionary <VariableSave, InterpolationCharacteristic>(); CreateStartingValueVariables(elementSave, states, currentBlock, interpolationCharacteristics); currentBlock = currentBlock.Switch("firstState"); currentBlock = SetInterpolateBetweenValuesForStates(elementSave, enumType, states, currentBlock, interpolationCharacteristics, FirstValue); currentBlock = currentBlock.End(); currentBlock = currentBlock.Switch("secondState"); currentBlock = SetInterpolateBetweenValuesForStates(elementSave, enumType, states, currentBlock, interpolationCharacteristics, SecondValue); currentBlock = currentBlock.End(); currentBlock = AssignValuesUsingStartingValues(elementSave, currentBlock, interpolationCharacteristics); currentBlock = currentBlock.If("interpolationValue < 1"); string fieldToAssign; if (enumType == "VariableState") { fieldToAssign = "mCurrentVariableState"; } else { fieldToAssign = "mCurrent" + enumType + "State"; } currentBlock.Line(fieldToAssign + " = firstState;"); currentBlock = currentBlock.End().Else(); currentBlock.Line(fieldToAssign + " = secondState;"); currentBlock = currentBlock.End(); } }
private static ICodeBlock GetMakeUnusedFactory(ICodeBlock codeBlock, string factoryClassName, bool poolObjects) { string className = factoryClassName.Substring(0, factoryClassName.Length - "Factory".Length); codeBlock.Line("/// <summary>"); codeBlock.Line("/// Makes the argument objectToMakeUnused marked as unused. This method is generated to be used"); codeBlock.Line("/// by generated code. Use Destroy instead when writing custom code so that your code will behave"); codeBlock.Line("/// the same whether your Entity is pooled or not."); codeBlock.Line("/// </summary>"); codeBlock = codeBlock .Function("public static void", "MakeUnused", className + " objectToMakeUnused") .Line("MakeUnused(objectToMakeUnused, true);") .End() ._() .Line("/// <summary>") .Line("/// Makes the argument objectToMakeUnused marked as unused. This method is generated to be used") .Line("/// by generated code. Use Destroy instead when writing custom code so that your code will behave") .Line("/// the same whether your Entity is pooled or not.") .Line("/// </summary>") .Function("public static void", "MakeUnused", className + " objectToMakeUnused, bool callDestroy"); if (poolObjects) { codeBlock .Line("mPool.MakeUnused(objectToMakeUnused);") ._() .If("callDestroy") .Line("objectToMakeUnused.Destroy();") .End(); } else { // We still need to check if we should call destroy even if not pooled, because the parent may be pooled, in which case an infinite loop // can occur if we don't check the callDestroy value. More info on this bug: // http://www.hostedredmine.com/issues/413966 codeBlock .If("callDestroy") .Line("objectToMakeUnused.Destroy();"); } codeBlock = codeBlock.End(); return(codeBlock); }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { //////////////////////////EARLY OUT////////////////////////////////////// if (element is ScreenSave) { return(codeBlock); } ///////////////////////END EARLY OUT///////////////////////////////////// codeBlock = codeBlock.Function("public void", "MoveToLayer", "Layer layerToMoveTo"); foreach (NamedObjectSave nos in element.NamedObjects) { if (!nos.IsDisabled) { if (nos.GetAssetTypeInfo() != null && !string.IsNullOrEmpty(nos.GetAssetTypeInfo().RemoveFromLayerMethod)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); bool shouldSkip = GetShouldSkip(nos); if (!shouldSkip) { codeBlock.If("LayerProvidedByContainer != null") .Line(nos.GetAssetTypeInfo().RemoveFromLayerMethod.Replace("this", nos.InstanceName).Replace("mLayer", "LayerProvidedByContainer") + ";") .End(); codeBlock.Line(nos.GetAssetTypeInfo().LayeredAddToManagersMethod[0].Replace("this", nos.InstanceName).Replace("mLayer", "layerToMoveTo") + ";"); } NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } else if (nos.SourceType == SourceType.Entity && !string.IsNullOrEmpty(nos.SourceClassType)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); codeBlock.Line(nos.InstanceName + ".MoveToLayer(layerToMoveTo);"); NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } } } codeBlock.Line("LayerProvidedByContainer = layerToMoveTo;"); codeBlock = codeBlock.End(); return(codeBlock); }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { //////////////////////////EARLY OUT////////////////////////////////////// if (element is ScreenSave) { return codeBlock; } ///////////////////////END EARLY OUT///////////////////////////////////// codeBlock = codeBlock.Function("public void", "MoveToLayer", "Layer layerToMoveTo"); foreach (NamedObjectSave nos in element.NamedObjects) { if (!nos.IsDisabled) { if (nos.GetAssetTypeInfo() != null && !string.IsNullOrEmpty(nos.GetAssetTypeInfo().RemoveFromLayerMethod)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); bool shouldSkip = GetShouldSkip(nos); if (!shouldSkip) { codeBlock.If("LayerProvidedByContainer != null") .Line(nos.GetAssetTypeInfo().RemoveFromLayerMethod.Replace("this", nos.InstanceName).Replace("mLayer", "LayerProvidedByContainer") + ";") .End(); codeBlock.Line(nos.GetAssetTypeInfo().LayeredAddToManagersMethod[0].Replace("this", nos.InstanceName).Replace("mLayer", "layerToMoveTo") + ";"); } NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } else if (nos.SourceType == SourceType.Entity && !string.IsNullOrEmpty(nos.SourceClassType)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); codeBlock.Line(nos.InstanceName + ".MoveToLayer(layerToMoveTo);"); NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } } } codeBlock.Line("LayerProvidedByContainer = layerToMoveTo;"); codeBlock = codeBlock.End(); return codeBlock; }
public override ICodeBlock GenerateLoadStaticContent(ICodeBlock codeBlock, SaveClasses.IElement element) { #region For debugging record if we're using a global content manager codeBlock.Line("#if DEBUG"); codeBlock.If("contentManagerName == FlatRedBall.FlatRedBallServices.GlobalContentManager") .Line("HasBeenLoadedWithGlobalContentManager = true;"); codeBlock.ElseIf("HasBeenLoadedWithGlobalContentManager") .Line("throw new System.Exception(\"This type has been loaded with a Global content manager, then loaded with a non-global. This can lead to a lot of bugs\");"); codeBlock.Line("#endif"); #endregion return(codeBlock); }
internal static void GenerateEventRaisingCode(ICodeBlock codeBlock, BeforeOrAfter beforeOrAfter, string variableName, IElement saveObject) { PerformancePluginCodeGenerator.CodeBlock = codeBlock; PerformancePluginCodeGenerator.SaveObject = saveObject; string beforeOrAfterAsString = "Before"; if (beforeOrAfter == BeforeOrAfter.After) { beforeOrAfterAsString = "After"; } PerformancePluginCodeGenerator.GenerateStart(beforeOrAfterAsString + " set " + variableName); codeBlock.If(beforeOrAfterAsString + variableName + "Set != null") .Line(beforeOrAfterAsString + variableName + "Set(this, null);"); PerformancePluginCodeGenerator.GenerateEnd(); }
public override ICodeBlock GenerateLoadStaticContent(ICodeBlock codeBlock, SaveClasses.IElement element) { #region For debugging record if we're using a global content manager codeBlock.Line("#if DEBUG"); codeBlock.If("contentManagerName == FlatRedBall.FlatRedBallServices.GlobalContentManager") .Line("HasBeenLoadedWithGlobalContentManager = true;"); codeBlock.ElseIf("HasBeenLoadedWithGlobalContentManager") .Line("throw new System.Exception(\"This type has been loaded with a Global content manager, then loaded with a non-global. This can lead to a lot of bugs\");"); codeBlock.Line("#endif"); #endregion return codeBlock; }
private ICodeBlock AssignValuesUsingStartingValues(ElementSave element, ICodeBlock curBlock, Dictionary <VariableSave, InterpolationCharacteristic> mInterpolationCharacteristics) { foreach (KeyValuePair <VariableSave, InterpolationCharacteristic> kvp in mInterpolationCharacteristics) { var variable = kvp.Key; if (kvp.Value != InterpolationCharacteristic.CantInterpolate) { string stringSuffix = variable.MemberNameInCode(element, VariableNamesToReplaceForStates).Replace(".", ""); curBlock = curBlock.If("set" + stringSuffix + FirstValue + " && set" + stringSuffix + SecondValue); AddAssignmentForInterpolationForVariable(curBlock, variable, element); curBlock = curBlock.End(); } } return(curBlock); }
private void GenerateAssignReferencesMethod(ElementSave elementSave, ICodeBlock currentBlock) { currentBlock = currentBlock.Function("private void", "AssignReferences", ""); { foreach (var instance in elementSave.Instances) { var foundBase = Gum.Managers.ObjectFinder.Self.GetElementSave(instance.BaseType); if (foundBase != null) { currentBlock.Line(instance.MemberNameInCode() + // Use the actual instance name rather than MemberNameInCode here, because it may differ // if there's invalid member characters like dashes $" = this.GetGraphicalUiElementByName(\"{instance.Name}\") as " + GueDerivingClassCodeGenerator.GetQualifiedRuntimeTypeFor(instance) + ";"); foreach (var eventSave in elementSave.Events.Where(item => item.GetSourceObject() == instance.Name && !string.IsNullOrEmpty(item.ExposedAsName))) { currentBlock.Line(eventSave.Name + " += Raise" + eventSave.ExposedAsName + ";"); } } } List <EventSave> exposedChildrenEvents = EventCodeGenerator.Self.GetExposedChildrenEvents(elementSave); foreach (var exposedChildEvent in exposedChildrenEvents) { currentBlock.Line($"{exposedChildEvent.Name} += (unused) => {exposedChildEvent.ExposedAsName}?.Invoke(this);"); } string controlType; var shouldGenerate = GetIfShouldGenerateFormsCode(elementSave, out controlType); if (shouldGenerate) { currentBlock .If("tryCreateFormsObject") .Line($"FormsControl = new {controlType}(this);"); } } }
public static ICodeBlock FillWithGeneratedEventCode(ICodeBlock currentBlock, EventResponseSave ers, IElement element) { EventSave eventSave = ers.GetEventSave(); string args = ers.GetArgsForMethod(element); if (!string.IsNullOrEmpty(ers.SourceObject) && !string.IsNullOrEmpty(ers.SourceObjectEvent)) { currentBlock = currentBlock .Function("void", "On" + ers.EventName + "Tunnel", args); string reducedArgs = StripTypesFromArguments(args); currentBlock.If("this." + ers.EventName + " != null") .Line(ers.EventName + "(" + reducedArgs + ");") .End(); currentBlock = currentBlock.End(); } return(currentBlock); }
private static ICodeBlock GeneratePreloadStateContentForStateType(ICodeBlock codeBlock, IElement element, List <StateSave> list, string variableType) { if (list.Count != 0) { codeBlock = codeBlock.Function("public static void", "PreloadStateContent", variableType + " state, string contentManagerName"); codeBlock.Line("ContentManagerName = contentManagerName;"); //codeBlock = codeBlock.Switch("state"); bool isElse = false; // Loop through states here and access properties that need the values foreach (StateSave state in list) { if (isElse) { codeBlock = codeBlock.ElseIf($"state == {variableType}.{state.Name}"); } else { codeBlock = codeBlock.If($"state == {variableType}.{state.Name}"); } isElse = true; foreach (InstructionSave instruction in state.InstructionSaves) { if (instruction.Value != null && instruction.Value is string) { // We insert a block so that object throwaway is not redefined in the switch scope. // We do this instead of making an object throwaway above the switch so that we don't // get warnings if is nothing to load codeBlock.Block().Line("object throwaway = " + GetRightSideAssignmentValueAsString(element, instruction) + ";"); } } codeBlock = codeBlock.End(); } codeBlock = codeBlock.End(); } return(codeBlock); }
private static void GenerateInitializationForCsvRfs(ReferencedFileSave referencedFile, ICodeBlock codeBlock, string variableName, string fileName, LoadType loadType) { var curBlock = codeBlock; // If it's not // a complete reload // then we don't care // about whether it's null // or not. if (referencedFile.IsSharedStatic && loadType == LoadType.CompleteLoad) { // Modify this line of code to use mVariable name if it's a global content and if we're doing async loading. // The reason is we can't query the property, because that would result in the property waiting until the content // is done loading - which would lock the game. // Update March 29, 2014 // Global content will now feed the variable name with 'm' prefixed // so we don't have to branch here anymore: //if (referencedFile.GetContainerType() == ContainerType.None && ProjectManager.GlueProjectSave.GlobalContentSettingsSave.LoadAsynchronously) //{ // curBlock = codeBlock.If(string.Format("{0} == null", variableName)); //} //else //{ // curBlock = codeBlock.If(string.Format("{0} == null", variableName)); //} curBlock = codeBlock.If(string.Format("{0} == null", variableName)); } GenerateCsvDeserializationCode(referencedFile, curBlock, variableName, fileName, loadType); }
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 static void GenerateAssignCustomVariables(ICodeBlock codeBlock, IElement element) { bool inherits = !string.IsNullOrEmpty(element.BaseElement) && !element.InheritsFromFrbType(); if (inherits) { codeBlock = codeBlock.Function("public override void", "AssignCustomVariables", "bool callOnContainedElements"); codeBlock.Line("base.AssignCustomVariables(callOnContainedElements);"); } else { codeBlock = codeBlock.Function("public virtual void", "AssignCustomVariables", "bool callOnContainedElements"); } // call AssignCustomVariables on all contained objects before assigning custom variables on "this" var ifCallOnContainedElements = codeBlock.If("callOnContainedElements"); var listOfItems = element.NamedObjects.Where(item=> item.IsFullyDefined && !item.IsDisabled && item.Instantiate && !item.SetByContainer && !item.SetByDerived ).ToList(); GenerateAssignmentForListOfObjects(codeBlock, element, ifCallOnContainedElements, listOfItems); foreach (CustomVariable customVariable in element.CustomVariables) { CustomVariableCodeGenerator.AppendAssignmentForCustomVariableInElement(codeBlock, customVariable, element); } EventCodeGenerator.GenerateAddToManagersBottomUp(codeBlock, element); }
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 AddTextSpecificAddToManagersCode(NamedObjectSave namedObject, ICodeBlock codeBlock, string objectName, string layerName) { // April 1, 2012 // Text that is added // through TextManager.AddText("Hello") // will automatically scale itself to be // pixel-perfect for the default Camera, or // to the Layer that it's added on. This behavior // is very handy but is a little more difficult to reproduce // with generated code. The reason for that is because generated // code adds Text objects to the Camera *after* variables are set on // the Text object (if they happen to be tunneled). Therefore, we need // to only set pixel perfect if the user has marked the text as being pixel // perfect. if (namedObject.SourceType == SourceType.FlatRedBallType && namedObject.SourceClassType == "Text" && namedObject.IsPixelPerfect) { codeBlock.If(objectName + ".Font != null") .Line(objectName + ".SetPixelPerfectScale(" + layerName + ");"); } }
public override ICodeBlock GenerateAdditionalMethods(ICodeBlock codeBlock, FlatRedBall.Glue.SaveClasses.IElement element) { //////////////////////////EARLY OUT////////////////////////////////////// if (element is ScreenSave) { return codeBlock; } ///////////////////////END EARLY OUT///////////////////////////////////// bool isInDerived = element.InheritsFromElement(); if (isInDerived) { codeBlock = codeBlock.Function("public override void", "MoveToLayer", "FlatRedBall.Graphics.Layer layerToMoveTo"); codeBlock.Line("base.MoveToLayer(layerToMoveTo);"); } else { codeBlock = codeBlock.Function("public virtual void", "MoveToLayer", "FlatRedBall.Graphics.Layer layerToMoveTo"); } if (element.InheritsFromFrbType()) { AssetTypeInfo ati = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(element.BaseElement); if (ati != null ) { if (ati.RemoveFromLayerMethod != null) { codeBlock.If("LayerProvidedByContainer != null") .Line(ati.RemoveFromLayerMethod.Replace("mLayer", "LayerProvidedByContainer") + ";") .End(); } if (ati.LayeredAddToManagersMethod.Count != 0) { codeBlock.Line(ati.LayeredAddToManagersMethod[0].Replace("mLayer", "layerToMoveTo") + ";"); } } } foreach (NamedObjectSave nos in element.NamedObjects) { if (!nos.IsDisabled && !nos.IsContainer) { bool shouldCheckForNull = nos.Instantiate == false; if (nos.GetAssetTypeInfo() != null && !string.IsNullOrEmpty(nos.GetAssetTypeInfo().RemoveFromLayerMethod)) { NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); bool shouldSkip = GetShouldSkip(nos); if (!shouldSkip) { if (shouldCheckForNull) { codeBlock = codeBlock.If(nos.InstanceName + " != null"); } codeBlock.If("LayerProvidedByContainer != null") .Line(nos.GetAssetTypeInfo().RemoveFromLayerMethod.Replace("this", nos.InstanceName).Replace("mLayer", "LayerProvidedByContainer") + ";") .End(); codeBlock.Line(nos.GetAssetTypeInfo().LayeredAddToManagersMethod[0].Replace("this", nos.InstanceName).Replace("mLayer", "layerToMoveTo") + ";"); if (shouldCheckForNull) { codeBlock = codeBlock.End(); } } NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); } else if (nos.SourceType == SourceType.Entity && !string.IsNullOrEmpty(nos.SourceClassType)) { if (shouldCheckForNull) { codeBlock = codeBlock.If(nos.InstanceName + " != null"); } NamedObjectSaveCodeGenerator.AddIfConditionalSymbolIfNecesssary(codeBlock, nos); codeBlock.Line(nos.InstanceName + ".MoveToLayer(layerToMoveTo);"); NamedObjectSaveCodeGenerator.AddEndIfIfNecessary(codeBlock, nos); if (shouldCheckForNull) { codeBlock = codeBlock.End(); } } } } codeBlock.Line("LayerProvidedByContainer = layerToMoveTo;"); codeBlock = codeBlock.End(); return codeBlock; }
public static void GetDestroyForNamedObject(IElement element, NamedObjectSave namedObject, ICodeBlock codeBlock, bool forceRecycle = false) { #region EARLY OUTS if (GetShouldSkipDestroyOn(namedObject)) { return; } #endregion bool shouldRecycle = forceRecycle || (element is EntitySave && (element as EntitySave).CreatedByOtherEntities); AddIfConditionalSymbolIfNecesssary(codeBlock, namedObject); #region Update dependencies // Update April 3, 2011 // The generated code used // to call UpdateDependencies // on any contained NamedObjectSave. // We did this because we wanted to make // sure that all contained NamedObjectSaves // were updated so when the Entity is recycled, // the contained NamedObjectSaves are in the proper. // position...or at least that was how things used to // be done. Now when AddToManagers is called on an Entity, // the Entity is moved back to the origin (and unrotated). This // means that we don't need to worry about this anymore: //if ( SaveObject is EntitySave && // (SaveObject as EntitySave).CreatedByOtherEntities && // (namedObject.AttachToContainer || namedObject.AttachToCamera)) //{ // // Why do we do this? The reason is because it's possible (and likely) that the Entity that this code // // is being generated for may be moving. Any attached objects will "lag behind" until the Draw method is // // called which updates dependencies. But Entities are usually destroyed before this update happens. If the // // Entity that is destroyed is re-cycled, then all attached objects will be offset slightly. This can build up // // over time and cause issues. This should help eliminate a lot of bugs. // if (namedObject.SourceType == SourceType.Entity || // (namedObject.AssetTypeInfo != null && namedObject.AssetTypeInfo.ShouldAttach)) // { // stringBuilder.AppendLine(tabs + namedObject.InstanceName + ".UpdateDependencies(TimeManager.CurrentTime);"); // } //} #endregion AssetTypeInfo ati = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(namedObject.InstanceType); #region If object was added to manager, remove this object from managers if (ati != null && namedObject.AddToManagers) { string removalMethod = null; if (shouldRecycle && !string.IsNullOrEmpty(ati.RecycledDestroyMethod)) { removalMethod = ati.RecycledDestroyMethod.Replace("this", namedObject.InstanceName); } else { if (ati.DestroyMethod != null) { removalMethod = ati.DestroyMethod.Replace("this", namedObject.InstanceName); } } if (!string.IsNullOrEmpty(removalMethod)) { codeBlock.If(namedObject.InstanceName + " != null") .Line(removalMethod + ";"); } } #endregion // TODO: Do we want to handle this case for pooled objects? I think so. #region If the object is an Entity, destroy the object and unload the static content if (namedObject.SourceType == SourceType.Entity) { var ifBlock = codeBlock.If(namedObject.InstanceName + " != null"); ifBlock.Line(namedObject.InstanceName + ".Destroy();"); if(!forceRecycle) { // We also detach so that if the object is recycled its Parent will be null ifBlock .Line(namedObject.InstanceName + ".Detach();"); } // Vic says: We used to manually call UnloadStaticContent on all Entities. But this // doesn't work well with inheritance. Instead, we now use the ContentManagers UnloadContent method support // GenerateStaticDestroyForType(tabs, namedObject.ClassType); } #endregion #region Special case Camera if (namedObject.SourceType == SourceType.FlatRedBallType && namedObject.SourceClassType == "Camera" && namedObject.IsNewCamera) { codeBlock.Line("FlatRedBall.SpriteManager.Cameras.Remove(" + namedObject.InstanceName + ");"); } #endregion #region Special case PositionedObjectList if (namedObject.IsList && namedObject.IsFullyDefined) { bool shouldSkip = namedObject.SetByContainer; if (!shouldSkip) { var forBlock = codeBlock.For(string.Format("int i = {0}.Count - 1; i > -1; i--", namedObject.InstanceName)); bool isEntity = ObjectFinder.Self.GetEntitySave(namedObject.SourceClassGenericType) != null; if (isEntity) { forBlock.Line(namedObject.InstanceName + "[i].Destroy();"); } else { string genericClassType = namedObject.SourceClassGenericType; AssetTypeInfo atiForListElement = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(genericClassType); if (atiForListElement != null && atiForListElement.DestroyMethod != null) { string removalMethod = atiForListElement.DestroyMethod.Replace("this", namedObject.InstanceName + "[i]"); if (!string.IsNullOrEmpty(removalMethod)) { forBlock.Line(removalMethod + ";"); } } else { forBlock.Line(string.Format("FlatRedBall.SpriteManager.RemovePositionedObject({0}[i]);", namedObject.InstanceName)); } } string genericType = namedObject.SourceClassGenericType; if (genericType.Contains("\\")) { genericType = genericType.Substring(genericType.IndexOf("\\") + 1); } } // Vic says: We used to manually call UnloadStaticContent on all Entities. But this // doesn't work well with inheritance. Instead, we now use the ContentManagers UnloadContent method support // GenerateStaticDestroyForType(tabs, genericType); } #endregion AddEndIfIfNecessary(codeBlock, namedObject); }
public static void GetPostCustomActivityForNamedObjectSave(IElement container, NamedObjectSave namedObjectSave, ICodeBlock codeBlock) { if (!string.IsNullOrEmpty(namedObjectSave.ClassType)) { AssetTypeInfo ati = namedObjectSave.GetAssetTypeInfo();// AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(namedObjectSave.ClassType); if (ati != null && !string.IsNullOrEmpty(ati.AfterCustomActivityMethod)) { bool shouldGenerate = true; if (namedObjectSave.SourceType == SourceType.File && !string.IsNullOrEmpty(namedObjectSave.SourceFile)) { ReferencedFileSave rfs = container.GetReferencedFileSaveRecursively(namedObjectSave.SourceFile); if (rfs != null && !rfs.IsSharedStatic) { shouldGenerate = false; } } if (shouldGenerate) { bool wrappInNullCheck = namedObjectSave.Instantiate == false; if (wrappInNullCheck) { codeBlock = codeBlock.If(namedObjectSave.InstanceName + " != null"); } codeBlock.Line(ati.AfterCustomActivityMethod.Replace("this", namedObjectSave.InstanceName) + ";"); if (wrappInNullCheck) { codeBlock = codeBlock.End(); } } } } }
public override ICodeBlock GenerateUnloadStaticContent(ICodeBlock codeBlock, IElement element) { // We'll assume that we want to get rid of the last one // The user may have loaded content from an Entity without calling LoadStaticContent - like if the // Entity is a LoadedOnlyWhenReferenced container. In that case, we need to make sure we account for // that by only removing if there are actually loaded content managers codeBlock = codeBlock.If("LoadedContentManagers.Count != 0"); codeBlock.Line("LoadedContentManagers.RemoveAt(0);"); codeBlock.Line("mRegisteredUnloads.RemoveAt(0);"); codeBlock = codeBlock.End(); codeBlock = codeBlock.If("LoadedContentManagers.Count == 0"); for (int i = 0; i < element.ReferencedFiles.Count; i++) { if (element.ReferencedFiles[i].IsSharedStatic && element.ReferencedFiles[i].GetGeneratesMember()) { ReferencedFileSave rfs = element.ReferencedFiles[i]; AddIfConditionalSymbolIfNecesssary(codeBlock, rfs); string variableName = rfs.GetInstanceName(); string fieldName = variableName; if (rfs.LoadedOnlyWhenReferenced) { fieldName = "m" + variableName; } AssetTypeInfo ati = rfs.GetAssetTypeInfo(); codeBlock = codeBlock .If(fieldName + " != null"); // Vic says - since now static referenced file saves just represent the last-loaded, we don't // want them to be removed anymore. //stringBuilder.AppendLine(string.Format("{0}{1};", tabs, ati.DestroyMethod.Replace("this", variableName))); //stringBuilder.AppendLine(string.Format("{0}{1} = null;", tabs, fieldName)); // But we do want to null them out if they are loaded only when referenced // Update on May 2, 2011 // This is actually a problem with Entities because // you can move from Screen to Screen and accumulate // static references to objects which don't get removed // which can cause some pretty nasty accumulation errors. // Therefore, I really do think we should always call Destroy and remove the object. // I can't think of why we wouldn't, actually. Perhaps the comment above was written // before we had a very advanced pattern in place. //if (rfs.LoadedOnlyWhenReferenced) { // We want to call destroy on the object, // but some types, like the AnimationChainList, // don't have destroy methods. Therefore, we should // check if destroy exists and append a destroy call if // so. // Files like .CSV may // be part of an Entity // but these will not have // an AssetTypeInfo, so we need // to check for that. if (ati != null && !string.IsNullOrEmpty(ati.DestroyMethod)) { codeBlock.Line(ati.DestroyMethod.Replace("this", fieldName) + ";"); } codeBlock.Line(fieldName + "= null;"); } codeBlock = codeBlock.End(); AddEndIfIfNecessary(codeBlock, rfs); } } codeBlock = codeBlock.End(); return codeBlock; }
internal static void GenerateExceptionForPostInitializeLoads(ICodeBlock curBlock) { if (ProjectManager.GlueProjectSave.PerformanceSettingsSave.ThrowExceptionOnPostInitializeContentLoad) { // This used // to always be // generated, but // now we only generate // it if the setting is set // to true. This elminates a // lot of unreachable code warnings. //stringBuilder.AppendLine(tabs + "const bool throwExceptionIfAfterInitialize = true;"); // curBlock.If("throwExceptionIfAfterInitialize && registerUnload && ScreenManager.CurrentScreen != null" + // Update: Actually why do we even need registerUnload? // curBlock.If("registerUnload && ScreenManager.CurrentScreen != null && FlatRedBall.FlatRedBallServices.IsThreadPrimary()" + // Update: If this requires primary thread loading then we'll actually be doing // the "async" loading on the primary thread, so we shouldn't throw an exception. curBlock.Line("#if !REQUIRES_PRIMARY_THREAD_LOADING"); curBlock.If("FlatRedBall.Screens.ScreenManager.CurrentScreen != null && FlatRedBall.FlatRedBallServices.IsThreadPrimary()" + " && FlatRedBall.Screens.ScreenManager.CurrentScreen.ActivityCallCount > 0 && !FlatRedBall.Screens.ScreenManager.CurrentScreen.IsActivityFinished") .Line("throw new System.InvalidOperationException(\"Content is being loaded after the current Screen is initialized. " + "This exception is being thrown because of a setting in Glue.\");") .End(); curBlock.Line("#endif"); } }
private ICodeBlock GenerateInterpolateToStateAdvanced(ICodeBlock codeBlock, string enumName) { codeBlock = codeBlock.Function("public void", "InterpolateToState", enumName + " fromState, " + enumName + " toState, double secondsToTake, FlatRedBall.Glue.StateInterpolation.InterpolationType interpolationType, FlatRedBall.Glue.StateInterpolation.Easing easing"); string variableName; if (enumName == "VariableState") { variableName = "CurrentState"; } else { variableName = "Current" + enumName + "State"; } codeBlock = codeBlock.If("secondsToTake <= 0"); codeBlock.Line(variableName + " = toState;"); codeBlock = codeBlock.End().Else(); // Immediately set the state to the from state: codeBlock.Line(variableName + " = fromState;"); codeBlock.Line("mFrom" + enumName + "Tween = fromState;"); codeBlock.Line("mTo" + enumName + "Tween = toState;"); codeBlock.Line( TweenerNameFor(enumName) + ".Start(0, 1, (float)secondsToTake, FlatRedBall.Glue.StateInterpolation.Tweener.GetInterpolationFunction(interpolationType, easing));"); codeBlock = codeBlock.End();// else codeBlock = codeBlock.End(); return codeBlock; }
private static void AddCodeForIsOn(ICodeBlock codeBlock, NamedObjectSave nos) { string condition = null; AssetTypeInfo ati = nos.GetAssetTypeInfo(); if (ati != null && ati.HasCursorIsOn) { bool shouldConsiderVisible = ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Sprite" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.ManagedSpriteGroups.SpriteFrame" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Graphics.Text"; bool shouldConsiderAlpha = ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Sprite" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.ManagedSpriteGroups.SpriteFrame" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Graphics.Text"; string whatToFormat; if (shouldConsiderVisible) { whatToFormat = "{0}.AbsoluteVisible && cursor.IsOn3D({0}, LayerProvidedByContainer)"; } else if (ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Scene") { whatToFormat = "cursor.IsOn3D({0}, LayerProvidedByContainer, false)"; } else { whatToFormat = "cursor.IsOn3D({0}, LayerProvidedByContainer)"; } if (shouldConsiderAlpha) { whatToFormat = "{0}.Alpha != 0 && " + whatToFormat; } condition = string.Format(whatToFormat, nos.InstanceName); } else if (nos.SourceType == SourceType.Entity) { EntitySave entitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassType); if (entitySave != null) { // This happens if: // The user has an Entity which is IWindow // The user adds a new object // The user sets the object to Entity - this will cause a code regeneration and this will be null; if (entitySave.ImplementsIWindow || entitySave.ImplementsIClickable) { condition = string.Format("{0}.HasCursorOver(cursor)", nos.InstanceName); } } } if (condition != null) { codeBlock.If(condition) .Line("return true;"); } }
private static void WriteLoadedOnlyWhenReferencedPropertyBody(ReferencedFileSave referencedFile, string containerName, IElement element, string contentManagerName, AssetTypeInfo ati, string variableName, string lastContentManagerVariableName, ICodeBlock getBlock) { string referencedFileName = GetFileToLoadForRfs(referencedFile, ati); string mThenVariableName = "m" + variableName; ICodeBlock ifBlock = null; if (element == null) { ifBlock = getBlock.If(mThenVariableName + " == null"); } else { string contentManagerToCompareAgainst; if (element is ScreenSave) { contentManagerToCompareAgainst = "\"" + FileManager.RemovePath(element.Name) + "\""; } else { contentManagerToCompareAgainst = "ContentManagerName"; } string conditionContents = mThenVariableName + " == null || " + lastContentManagerVariableName + " != " + contentManagerToCompareAgainst; bool isDisposable = referencedFile.RuntimeType == "Texture2D" || referencedFile.RuntimeType == "Microsoft.Xna.Framework.Graphics.Texture2D"; if (isDisposable) { conditionContents += " || " + mThenVariableName + ".IsDisposed"; } ifBlock = getBlock.If(conditionContents); ifBlock.Line(lastContentManagerVariableName + " = " + contentManagerToCompareAgainst + ";"); } if (containerName != ContentLoadWriter.GlobalContentContainerName) { GenerateExceptionForPostInitializeLoads(getBlock); } PerformancePluginCodeGenerator.CodeBlock = ifBlock; PerformancePluginCodeGenerator.SaveObject = element; PerformancePluginCodeGenerator.GenerateStart(" Get " + variableName); if (ati != null && !referencedFile.IsCsvOrTreatedAsCsv) { GetLoadCallForAtiFile(referencedFile, ati, mThenVariableName, contentManagerName, ProjectBase.AccessContentDirectory + referencedFileName, ifBlock); } else if (referencedFile.IsCsvOrTreatedAsCsv) { GenerateCsvDeserializationCode(referencedFile, ifBlock, mThenVariableName, referencedFileName, LoadType.CompleteLoad); } if (element != null && element is EntitySave) { AppendAddUnloadMethod(ifBlock, containerName); } PerformancePluginCodeGenerator.GenerateEnd(); getBlock.Line("return " + mThenVariableName + ";"); }
private ICodeBlock AssignValuesUsingStartingValues(ElementSave element, ICodeBlock curBlock, Dictionary<VariableSave, InterpolationCharacteristic> mInterpolationCharacteristics) { foreach (KeyValuePair<VariableSave, InterpolationCharacteristic> kvp in mInterpolationCharacteristics) { var variable = kvp.Key; if (kvp.Value != InterpolationCharacteristic.CantInterpolate) { string stringSuffix = variable.MemberNameInCode(element, mVariableNamesToReplaceForStates).Replace(".", ""); curBlock = curBlock.If("set" + stringSuffix + FirstValue + " && set" + stringSuffix + SecondValue); AddAssignmentForInterpolationForVariable(curBlock, variable, element); curBlock = curBlock.End(); } } return curBlock; }
private static void GenerateInterpolateForIndividualStateNoSource(ref ICodeBlock codeBlock, IElement element, ref ICodeBlock otherBlock, InstructionSave instruction, CustomVariable customVariable, string valueAsString, string timeCastString) { string velocityMember = FlatRedBall.Instructions.InstructionManager.GetVelocityForState(instruction.Member); // If the velocityMember exists, we need to make sure it's actually exposable if (!ExposedVariableManager.GetExposableMembersFor(element, false).Any(item => item.Member == velocityMember)) { velocityMember = null; } if (velocityMember == null && customVariable.HasAccompanyingVelocityProperty) { velocityMember = customVariable.Name + "Velocity"; } if (!string.IsNullOrEmpty(velocityMember)) { string relativeVelocity = InstructionManager.GetRelativeForAbsolute(velocityMember); string leftHandPlusEquals = null; if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock .If("this.Parent != null"); otherBlock = otherBlock .If("this.Parent != null"); string instructionMemberRelative = InstructionManager.GetRelativeForAbsolute(instruction.Member); leftHandPlusEquals = relativeVelocity + " = "; codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + instructionMemberRelative + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); codeBlock = codeBlock .End() .Else(); otherBlock = otherBlock .End() .Else(); } leftHandPlusEquals = velocityMember + " = "; codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + instruction.Member + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock.End(); otherBlock = otherBlock.End(); } } }
private ICodeBlock SetInterpolateBetweenValuesForStates(ElementSave element, string enumType, IEnumerable<StateSave> states, ICodeBlock curBlock, Dictionary<VariableSave, InterpolationCharacteristic> mInterpolationCharacteristics, string firstOrSecondValue) { foreach (StateSave state in states) { curBlock = curBlock.Case(enumType + "." + state.MemberNameInCode()); foreach (VariableSave variable in state.Variables.Where(item => GetIfShouldGenerateStateVariable(item, element))) { var nameInCode = variable.MemberNameInCode(element, mVariableNamesToReplaceForStates); if (GetValue(mInterpolationCharacteristics, nameInCode, element) != InterpolationCharacteristic.CantInterpolate) { string stringSuffix = variable.MemberNameInCode(element, mVariableNamesToReplaceForStates).Replace(".", ""); if (variable.Value == null) { //curBlock.Line("set" + stringSuffix + " = false;"); } else { string variableValue = variable.Value.ToString(); bool isEntireAssignment; GueDerivingClassCodeGenerator.Self.AdjustVariableValueIfNecessary(variable, element, ref variableValue, out isEntireAssignment); if (isEntireAssignment) { throw new NotImplementedException(); } else { curBlock.Line("set" + stringSuffix + firstOrSecondValue + " = true;"); curBlock.Line(variable.MemberNameInCode(element, mVariableNamesToReplaceForStates).Replace(".", "") + firstOrSecondValue + " = " + variableValue + ";"); } } } else if (variable.Value != null) // This value can't be interpolated, but if the user has set a value of 0 or 1, then it should be set { ICodeBlock ifBlock; // value will come from the first state unless the interpolationValue is 1. // This makes the code behave the same as InterpolateTo which uses instructions. if (firstOrSecondValue == FirstValue) { ifBlock = curBlock.If("interpolationValue < 1"); } else { ifBlock = curBlock.If("interpolationValue >= 1"); } string variableValue = variable.Value.ToString(); bool isEntireAssignment; GueDerivingClassCodeGenerator.Self.AdjustVariableValueIfNecessary(variable, element, ref variableValue, out isEntireAssignment); if(isEntireAssignment) { ifBlock.Line(variableValue); } else { ifBlock.Line("this." + nameInCode + " = " + variableValue + ";"); } } } curBlock = curBlock.End(); } return curBlock; }
public static void WriteConvertToManuallyUpdated(ICodeBlock codeBlock, IElement element, List<string[]> reusableEntireFileRfses) { foreach (NamedObjectSave nos in element.NamedObjects) { if ((nos.IsList || nos.AddToManagers) && !nos.IsDisabled && !nos.InstantiatedByBase && nos.IsFullyDefined && nos.IsContainer == false) { AddIfConditionalSymbolIfNecesssary(codeBlock, nos); bool shouldHaveIfNullCheck = nos.Instantiate == false || nos.SetByDerived; if (shouldHaveIfNullCheck) { codeBlock = codeBlock.If(nos.InstanceName + " != null"); } #region The NOS is an Entity if (nos.SourceType == SourceType.Entity) { codeBlock.Line(nos.InstanceName + ".ConvertToManuallyUpdated();"); } #endregion #region The NOS is a PositionedObjectList else if (nos.IsList && !string.IsNullOrEmpty(nos.SourceClassGenericType)) { WriteConvertToManuallyUpdatedForListNos(codeBlock, nos); } #endregion else { AssetTypeInfo ati = nos.GetAssetTypeInfo(); bool alreadyHandledByEntireFileObject = false; if (nos.SourceType == SourceType.File && !string.IsNullOrEmpty(nos.SourceFile) && !string.IsNullOrEmpty(nos.SourceName) && !nos.SourceName.StartsWith("Entire File (")) { foreach (string[] stringPair in reusableEntireFileRfses) { if (stringPair[0] == nos.SourceFile) { alreadyHandledByEntireFileObject = true; break; } } } if (!alreadyHandledByEntireFileObject && ati != null && !string.IsNullOrEmpty(ati.MakeManuallyUpdatedMethod)) { codeBlock.Line(ati.MakeManuallyUpdatedMethod.Replace("this", nos.InstanceName) + ";"); } } if (shouldHaveIfNullCheck) { codeBlock = codeBlock.End(); } AddEndIfIfNecessary(codeBlock, nos); } } }
private void GenerateInterpolateTo(ElementSave elementSave, ICodeBlock codeBlock, IEnumerable<StateSave> states, string enumName) { string qualifiedEnum = GueDerivingClassCodeGenerator.GueRuntimeNamespace + "." + FlatRedBall.IO.FileManager.RemovePath( elementSave.Name) + "Runtime." + enumName; // Make this thing return the Tweener so the uer can customize it string parameters = qualifiedEnum + " fromState," + qualifiedEnum + " toState, double secondsToTake, " + "FlatRedBall.Glue.StateInterpolation.InterpolationType interpolationType, FlatRedBall.Glue.StateInterpolation.Easing easing, object owner = null"; codeBlock = codeBlock.Function("public FlatRedBall.Glue.StateInterpolation.Tweener", "InterpolateTo", parameters); { codeBlock.Line("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from:0, to:1, duration:(float)secondsToTake, type:interpolationType, easing:easing );"); codeBlock.If("owner == null") .Line("tweener.Owner = this;") .End() .Else() .Line("tweener.Owner = owner;"); codeBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(fromState, toState, newPosition);"); codeBlock.Line("tweener.Start();"); codeBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); codeBlock.Line("return tweener;"); } }
static void AssignResetVariables(ICodeBlock codeBlock, List<NamedObjectSave> namedObjects) { foreach (NamedObjectSave namedObject in namedObjects) { if (namedObject.SetByDerived || namedObject.SetByContainer || namedObject.IsDisabled) { continue; } AssetTypeInfo ati = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(namedObject.InstanceType); if (ati != null && ati.IsInstantiatedInAddToManagers) { // This is an object which has to be instantiated by the engine (like Layer), so it will // stay null until we call AddToManagers continue; } for (int i = 0; i < namedObject.VariablesToReset.Count; i++) { string relativeVariable = null; if (namedObject.SourceType == SourceType.Entity || (ati != null && ati.ShouldAttach)) { relativeVariable = InstructionManager.GetRelativeForAbsolute(namedObject.VariablesToReset[i]); } if (!string.IsNullOrEmpty(relativeVariable)) { codeBlock = codeBlock.If(namedObject.InstanceName + ".Parent == null"); } codeBlock.Line(namedObject.InstanceName + namedObject.VariablesToReset[i].Replace(".", "") + "Reset" + " = " + namedObject.InstanceName + "." + namedObject.VariablesToReset[i] + ";"); if (!string.IsNullOrEmpty(relativeVariable)) { codeBlock = codeBlock.End().Else(); codeBlock.Line(namedObject.InstanceName + namedObject.VariablesToReset[i].Replace(".", "") + "Reset" + " = " + namedObject.InstanceName + "." + relativeVariable + ";"); codeBlock = codeBlock.End(); } } AssignResetVariables(codeBlock, namedObject.ContainedObjects); } }
private static ICodeBlock ApplyResetVariables(NamedObjectSave namedObject, ICodeBlock codeBlock, AssetTypeInfo ati) { // Also reset variables before attachment. // May 15, 2011: This should happen before // setting the custom variables. // May 16, 2011: CustomVariables which are // exposed variables are now set before AddToManagers // is even called. Therefore, doing this before doesn't matter // anymore. Moved back down to its old position. for (int i = 0; i < namedObject.VariablesToReset.Count; i++) { string variableToReset = namedObject.VariablesToReset[i]; string relativeVersion = InstructionManager.GetRelativeForAbsolute(namedObject.VariablesToReset[i]); if ((namedObject.SourceType == SourceType.Entity || ati.ShouldAttach) && !string.IsNullOrEmpty(relativeVersion)) { codeBlock = codeBlock.If(namedObject.InstanceName + ".Parent == null"); } codeBlock.Line(namedObject.InstanceName + "." + namedObject.VariablesToReset[i] + " = " + namedObject.InstanceName + namedObject.VariablesToReset[i].Replace(".", "") + "Reset" + ";"); if ((namedObject.SourceType == SourceType.Entity || ati.ShouldAttach) && !string.IsNullOrEmpty(relativeVersion)) { codeBlock = codeBlock.End().Else(); codeBlock.Line(namedObject.InstanceName + "." + relativeVersion + " = " + namedObject.InstanceName + namedObject.VariablesToReset[i].Replace(".", "") + "Reset" + ";"); codeBlock = codeBlock.End(); } } return codeBlock; }
private static void AddLayerSpecificAddToManagersCode(NamedObjectSave namedObject, ICodeBlock codeBlock, string objectName) { if (namedObject.IsLayer && namedObject.IndependentOfCamera) { if (namedObject.Is2D) { codeBlock.Line(objectName + ".UsePixelCoordinates();"); if (namedObject.DestinationRectangle != null) { float leftDestination = namedObject.DestinationRectangle.Value.X; float topDestination = namedObject.DestinationRectangle.Value.Y; float rightDestination = (namedObject.DestinationRectangle.Value.X + namedObject.DestinationRectangle.Value.Width); float bottomDestination = bottomDestination = (namedObject.DestinationRectangle.Value.Y + namedObject.DestinationRectangle.Value.Height); if (namedObject.LayerCoordinateUnit == LayerCoordinateUnit.Pixel) { codeBlock.Line(objectName + ".LayerCameraSettings.LeftDestination = " + FlatRedBall.Math.MathFunctions.RoundToInt( leftDestination ) + ";"); codeBlock.Line(objectName + ".LayerCameraSettings.TopDestination = " + FlatRedBall.Math.MathFunctions.RoundToInt(topDestination ) + ";"); codeBlock.Line(objectName + ".LayerCameraSettings.RightDestination = " + FlatRedBall.Math.MathFunctions.RoundToInt(rightDestination ) + ";"); codeBlock.Line(objectName + ".LayerCameraSettings.BottomDestination = " + FlatRedBall.Math.MathFunctions.RoundToInt(bottomDestination ) + ";"); codeBlock.Line(objectName + ".LayerCameraSettings.OrthogonalWidth = " + FlatRedBall.Math.MathFunctions.RoundToInt(namedObject.DestinationRectangle.Value.Width ) + ";"); codeBlock.Line(objectName + ".LayerCameraSettings.OrthogonalHeight = " + FlatRedBall.Math.MathFunctions.RoundToInt(namedObject.DestinationRectangle.Value.Height ) + ";"); } else { codeBlock.Line(objectName + ".LayerCameraSettings.LeftDestination = " + "FlatRedBall.Math.MathFunctions.RoundToInt(FlatRedBall.SpriteManager.Camera.DestinationRectangle.Right * " + (.01 * leftDestination) + ");"); codeBlock.Line(objectName + ".LayerCameraSettings.TopDestination = " + "FlatRedBall.Math.MathFunctions.RoundToInt(FlatRedBall.SpriteManager.Camera.DestinationRectangle.Bottom * " + (.01 * topDestination) + ");"); codeBlock.Line(objectName + ".LayerCameraSettings.BottomDestination = " + "FlatRedBall.Math.MathFunctions.RoundToInt(FlatRedBall.SpriteManager.Camera.DestinationRectangle.Bottom * " + (.01 * bottomDestination) + ");"); codeBlock.Line(objectName + ".LayerCameraSettings.RightDestination = " + "FlatRedBall.Math.MathFunctions.RoundToInt(FlatRedBall.SpriteManager.Camera.DestinationRectangle.Right * " + (.01 * rightDestination) + ");"); codeBlock.Line(objectName + ".LayerCameraSettings.OrthogonalWidth = " + "FlatRedBall.SpriteManager.Camera.OrthogonalWidth * (float)(" + (.01 * (rightDestination - leftDestination)) + ");"); codeBlock.Line(objectName + ".LayerCameraSettings.OrthogonalHeight = " + "FlatRedBall.SpriteManager.Camera.OrthogonalHeight * (float)(" + (.01 * (bottomDestination - topDestination)) + ");"); } } else if (namedObject.LayerCoordinateType == LayerCoordinateType.MatchCamera) { codeBlock = codeBlock.If("FlatRedBall.SpriteManager.Camera.Orthogonal"); codeBlock.Line(objectName + ".LayerCameraSettings.OrthogonalWidth = FlatRedBall.SpriteManager.Camera.OrthogonalWidth;"); codeBlock.Line(objectName + ".LayerCameraSettings.OrthogonalHeight = FlatRedBall.SpriteManager.Camera.OrthogonalHeight;"); codeBlock = codeBlock.End(); } } else { codeBlock.Line(objectName + ".LayerCameraSettings = new FlatRedBall.Graphics.LayerCameraSettings();"); codeBlock.Line(objectName + ".LayerCameraSettings.Orthogonal = false;"); } } }
private static void GenerateInterpolateForIndividualStateWithSource(ref ICodeBlock codeBlock, IElement element, ref ICodeBlock otherBlock, CustomVariable customVariable, string valueAsString, NamedObjectSave sourceNamedObjectSave, string timeCastString) { if (customVariable.GetIsVariableState()) { GenerateInterpolateForIndividualStateWithSourceStateVariable(codeBlock, customVariable, element, valueAsString.Replace("\"", "")); } else { string velocityMember = FlatRedBall.Instructions.InstructionManager.GetVelocityForState(customVariable.SourceObjectProperty); bool generatedVelocity = false; if (velocityMember == null && customVariable.HasAccompanyingVelocityProperty) { velocityMember = customVariable.Name + "Velocity"; generatedVelocity = true; } bool velocityComesFromTunnel = false; if (velocityMember == null && // Only want to go 1 deep. The reason is if the tunneled variable has a // velocity value, we can use that. However, if it's tunneled multiple times // into a variable that ultimately has a velocity variable we may not be able to // get to it, so we shouldn't just assume we can add "Velocity" to the variable name. customVariable.HasAccompanyingVelocityConsideringTunneling(element, 1)) { velocityMember = customVariable.SourceObjectProperty + "Velocity"; generatedVelocity = true; velocityComesFromTunnel = true; } if (!string.IsNullOrEmpty(velocityMember)) { string sourceDot = customVariable.SourceObject + "."; IEnumerable <string> exposableVariables = FlatRedBall.Glue.Reflection.ExposedVariableManager.GetExposableMembersFor(sourceNamedObjectSave).Select(item => item.Member); // We will generate this if the variable is contained in exposable variables, // if the user explicitly said to generate a velocity variable, or if // this is a FRB type. The reason we check if it's a FRB Type is because FRB // types have velocity variables which may not be exposable. We don't want Glue // to mess with temporary values like Velocity, so they are removed from the exposab // variable list: bool shouldGenerate = exposableVariables.Contains(velocityMember) || generatedVelocity || sourceNamedObjectSave.SourceType == SourceType.FlatRedBallType; if (shouldGenerate) { string relativeVelocity = InstructionManager.GetRelativeForAbsolute(velocityMember); string leftHandPlusEquals = null; if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock .If(customVariable.SourceObject + ".Parent != null"); otherBlock = otherBlock .If(customVariable.SourceObject + ".Parent != null"); string sourceObjectPropertyRelative = InstructionManager.GetRelativeForAbsolute(customVariable.SourceObjectProperty); leftHandPlusEquals = sourceDot + relativeVelocity + " = "; codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + sourceDot + sourceObjectPropertyRelative + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); codeBlock = codeBlock .End() .Else(); otherBlock = otherBlock .End() .Else(); } // If we're using a custom velocity value, we don't want to // use the sourceDot. We just want to use the velocity value if (generatedVelocity && !velocityComesFromTunnel) { leftHandPlusEquals = velocityMember + " = "; } else { leftHandPlusEquals = sourceDot + velocityMember + " = "; } codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + sourceDot + customVariable.SourceObjectProperty + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock.End(); otherBlock = otherBlock.End(); } } } } }
public static void GetPostInitializeForNamedObjectList(NamedObjectSave container, List<NamedObjectSave> namedObjectList, ICodeBlock codeBlock, IElement element) { foreach (NamedObjectSave nos in namedObjectList) { if (!nos.IsDisabled && nos.IsFullyDefined && nos.Instantiate) { // We should put the conditional compilation symbol before adding to a list: AddIfConditionalSymbolIfNecesssary(codeBlock, nos); // Sept 24, 2012 // This used to be // in LateInitialize, // but we moved it here. // See the LateInitialize // method for more information. if (container != null && !nos.InstantiatedByBase && nos.IsContainer == false) { bool shouldSkip = nos.SourceType == SourceType.File && string.IsNullOrEmpty(nos.SourceFile); if (!shouldSkip) { codeBlock.Line(container.InstanceName + ".Add(" + nos.InstanceName + ");"); } } EntitySave throwAway = null; ReferencedFileSave rfsReferenced = GetReferencedFileSaveReferencedByNamedObject(nos, element, ref throwAway); bool wrappInIf = nos.SetByDerived || nos.SetByContainer; // This may be a SetByDerived NOS, so it could be null if (wrappInIf) { codeBlock = codeBlock .If(nos.InstanceName + "!= null"); } if (nos.IsContainer == false) { WriteAttachTo(nos, codeBlock, ReusableEntireFileRfses, rfsReferenced); } GetPostInitializeForNamedObjectList(nos, codeBlock); GetPostInitializeForNamedObjectList(nos, nos.ContainedObjects, codeBlock, element); if (wrappInIf) { codeBlock = codeBlock.End(); } AddEndIfIfNecessary(codeBlock, nos); } } }
private void GenerateInterpolateToFromCurrent(ICodeBlock currentBlock, string enumType, bool isRelative) { string functionName = "InterpolateTo"; string whereToLook = "States"; if(enumType != "VariableState") { whereToLook = $"Categories.First(item => item.Name == \"{enumType}\").States"; } string toStateRightSide = $"this.ElementSave.{whereToLook}.First(item => item.Name == toState.ToString());"; if(isRelative) { functionName = "InterpolateToRelative"; toStateRightSide = "AddToCurrentValuesWithState(toState);"; } currentBlock = currentBlock.Function("public FlatRedBall.Glue.StateInterpolation.Tweener", functionName, enumType + " toState, double secondsToTake, FlatRedBall.Glue.StateInterpolation.InterpolationType interpolationType, FlatRedBall.Glue.StateInterpolation.Easing easing, object owner = null "); currentBlock.Line("Gum.DataTypes.Variables.StateSave current = GetCurrentValuesOnState(toState);"); currentBlock.Line("Gum.DataTypes.Variables.StateSave toAsStateSave = " + toStateRightSide); currentBlock.Line("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from: 0, to: 1, duration: (float)secondsToTake, type: interpolationType, easing: easing);"); currentBlock.If("owner == null") .Line("tweener.Owner = this;") .End() .Else() .Line("tweener.Owner = owner;"); currentBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(current, toAsStateSave, newPosition);"); string variableName; if(enumType == "VariableState") { variableName = "CurrentVariableState"; } else { variableName = $"Current{enumType}State"; } currentBlock.Line($"tweener.Ended += ()=> this.{variableName} = toState;"); currentBlock.Line("tweener.Start();"); currentBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); currentBlock.Line("return tweener;"); }
public static void GetActivityForNamedObject(NamedObjectSave namedObjectSave, ICodeBlock codeBlock) { ///////////////////////////EARLY OUT///////////////////////////////////////////////// if ( (namedObjectSave.SetByContainer && namedObjectSave.GetContainer() is EntitySave) || namedObjectSave.IsDisabled || namedObjectSave.CallActivity == false || namedObjectSave.InstantiatedByBase || !namedObjectSave.IsFullyDefined) { return; } /////////////////////////END EARLY OUT/////////////////////////////////////////////// bool setByDerived = namedObjectSave.SetByDerived; AddIfConditionalSymbolIfNecesssary(codeBlock, namedObjectSave); if (!setByDerived) { if (namedObjectSave.Instantiate == false) { // This may be null or it may be instantiated later by the user, so we should // handle both cases: codeBlock = codeBlock.If(namedObjectSave.InstanceName + " != null"); } if (namedObjectSave.SourceType == SourceType.Entity) { // Entities need activity! codeBlock.Line(namedObjectSave.InstanceName + ".Activity();"); } else if (namedObjectSave.SourceType == SourceType.FlatRedBallType && namedObjectSave.ClassType != null && namedObjectSave.ClassType.Contains("PositionedObjectList<")) { // Now let's see if the object in the list is an entity string genericType = namedObjectSave.SourceClassGenericType; if (genericType.Contains("Entities\\")) { codeBlock.For("int i = " + namedObjectSave.InstanceName + ".Count - 1; i > -1; i--") .If("i < " + namedObjectSave.InstanceName + ".Count") .Line("// We do the extra if-check because activity could destroy any number of entities") .Line(namedObjectSave.InstanceName + "[i].Activity();"); } } } // If it's an emitter, call TimedEmit: ParticleCodeGenerator.GenerateTimedEmit(codeBlock, namedObjectSave); if (!setByDerived) { if (namedObjectSave.Instantiate == false) { // end the if-statement we started above. codeBlock = codeBlock.End(); } } AddEndIfIfNecessary(codeBlock, namedObjectSave); }
private void GenerateDebugCheckForInterpolationValueNaN(ICodeBlock codeBlock) { codeBlock.Line("#if DEBUG"); codeBlock.If("float.IsNaN(interpolationValue)") .Line("throw new System.Exception(\"interpolationValue cannot be NaN\");") .End(); codeBlock.Line("#endif"); }
private static void GenerateAddCollisionAndEntities(ICodeBlock function) { var ifCode = function.If("levelInfoObject is System.Collections.Generic.List<DataTypes.TileMapInfo>"); { ifCode.Line("FlatRedBall.TileCollisions.TileShapeCollectionLayeredTileMapExtensions.AddCollisionFrom(" + "SolidCollisions, CurrentTileMap, levelInfoObject as System.Collections.Generic.List<DataTypes.TileMapInfo>);"); ifCode.Line("FlatRedBall.TileEntities.TileEntityInstantiator.CreateEntitiesFrom(" + "CurrentTileMap, levelInfoObject as System.Collections.Generic.List<DataTypes.TileMapInfo>);"); } var elseCode = ifCode.End().Else(); { elseCode.Line("FlatRedBall.TileCollisions.TileShapeCollectionLayeredTileMapExtensions.AddCollisionFrom(" + "SolidCollisions, CurrentTileMap, levelInfoObject as System.Collections.Generic.Dictionary<string, DataTypes.TileMapInfo>);"); elseCode.Line("FlatRedBall.TileEntities.TileEntityInstantiator.CreateEntitiesFrom(" + "CurrentTileMap, levelInfoObject as System.Collections.Generic.Dictionary<string, DataTypes.TileMapInfo>);"); } }
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};"); }