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 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"); // Loop through states here and access properties that need the values foreach (StateSave state in list) { codeBlock = codeBlock.Case(variableType + "." + state.Name); 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(); codeBlock = codeBlock.End(); } return(codeBlock); }
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 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 AppendEnum(ICodeBlock currentBlock, List <StateSave> statesForThisCategory, string enumName, IElement element) { if (statesForThisCategory.Count != 0) { string prefix = "public"; if (ShouldUseNewKeyword(element, enumName)) { prefix += " new"; } currentBlock = currentBlock .Enum(prefix, enumName) .Line("Uninitialized = 0, //This exists so that the first set call actually does something") .Line("Unknown = 1, //This exists so that if the entity is actually a child entity and has set a child state, you will get this"); for (int i = 0; i < statesForThisCategory.Count; i++) { string whatToAppend = ""; if (i != statesForThisCategory.Count - 1) { whatToAppend += ", "; } currentBlock.Line(statesForThisCategory[i].Name + " = " + (i + 2) + whatToAppend); } currentBlock = currentBlock.End(); } return(currentBlock); }
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 void CreateInstructionForInterpolation(StateCodeGeneratorContext context, ICodeBlock currentBlock, string animationType, AnimatedStateSave previousState, AnimatedStateSave currentState, AbsoluteOrRelative absoluteOrRelative, string animationName) { currentBlock = currentBlock.Block(); if (absoluteOrRelative == AbsoluteOrRelative.Absolute) { CreateInstructionForInterpolationAbsolute(context, currentBlock, animationType, previousState, currentState, animationName); } else { CreateInstructionForInterpolationRelative(context, currentBlock, previousState, currentState); } currentBlock = currentBlock.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 ICodeBlock GetInitializeFactoryMethod(ICodeBlock codeBlock, string className, bool poolObjects, string listToAssign) { codeBlock = codeBlock .Function("public static void", "Initialize", string.Format("string contentManager", className)) .Line("mContentManagerName = contentManager;"); if (poolObjects) { codeBlock.Line("FactoryInitialize();"); } codeBlock = codeBlock.End(); return(codeBlock); }
private static ICodeBlock GetInitializeFactoryMethod(ICodeBlock codeBlock, string className, bool poolObjects, string listToAssign) { codeBlock = codeBlock .Function("public static void", "Initialize", string.Format("FlatRedBall.Math.PositionedObjectList<{0}> listFromScreen, string contentManager", className)) .Line("mContentManagerName = contentManager;") .Line(listToAssign + " = listFromScreen;"); if (poolObjects) { codeBlock.Line("FactoryInitialize();"); } codeBlock = codeBlock.End(); return(codeBlock); }
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); }
internal static void GenerateAddToManagersBottomUp(ICodeBlock codeBlock, IElement element) { foreach (EventResponseSave ers in element.Events) { EventSave eventSave = ers.GetEventSave(); // Right now I'm hardcoding this event, but eventually we may want to pull this value from the data // if it's something we want to support on other events bool raiseInAddToManagers = eventSave != null && eventSave.EventName == "ResolutionOrOrientationChanged"; if (raiseInAddToManagers) { codeBlock.Line("OnResolutionOrOrientationChanged(this, null);"); codeBlock = codeBlock.End(); } } }
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); }
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); }
public static ICodeBlock FillWithCustomEventCode(ICodeBlock currentBlock, EventResponseSave ers, string contents, IElement element) { string args = ers.GetArgsForMethod(element); // We used to not // generate the empty // shell of an event if // the contents were empty. // However now we want to for // two reasons: // 1: A user may want to add an // event in Glue, but then mdoify // the event in Visual Studio. The // user shouldn't be forced into adding // some content in Glue first to wdit the // event in Visual Studio. // 2: A designer may decide to remove the // contents of a method. If this happens then // code that the designer doesn't work with shouldn't // break (IE, if the code calls the OnXXXX method). //if (!string.IsNullOrEmpty(contents)) { // Need to modify the event CSV to include the arguments for this event currentBlock = currentBlock .Function("void", "On" + ers.EventName, args); currentBlock.TabCharacter = ""; int tabCount = currentBlock.TabCount; currentBlock.TabCount = 0; currentBlock .Line(contents); currentBlock = currentBlock.End(); } return(currentBlock); }
private static void CreateInstructionForSubAnimation(ICodeBlock currentBlock, AnimationReferenceSave animationReferenceSave, AbsoluteOrRelative absoluteOrRelative, AnimationSave parentAnimation) { currentBlock = currentBlock.Block(); //var instruction = new FlatRedBall.Instructions.DelegateInstruction(() => //FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(ClickableBushInstance.GrowAnimation)); //instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + asdf; //yield return instruction; string animationName = animationReferenceSave.PropertyNameInCode(); //animationReferenceSave. FlatRedBall.IO.FileManager.RemovePath(animationReferenceSave.Name) + "Animation"; if (absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } currentBlock.Line($"var instruction = new FlatRedBall.Instructions.DelegateInstruction(()=>{animationName}.Play({parentAnimation.PropertyNameInCode()}));"); currentBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + ToFloatString(animationReferenceSave.Time) + ";"); currentBlock.Line("yield return instruction;"); currentBlock = currentBlock.End(); }
private static void CreateInstructionForSubAnimation(ICodeBlock currentBlock, AnimationReferenceSave animationReferenceSave, AbsoluteOrRelative absoluteOrRelative, AnimationSave parentAnimation, StateCodeGeneratorContext context) { currentBlock = currentBlock.Block(); //var instruction = new FlatRedBall.Instructions.DelegateInstruction(() => //FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(ClickableBushInstance.GrowAnimation)); //instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + asdf; //yield return instruction; var isReferencingMissingInstance = !string.IsNullOrEmpty(animationReferenceSave.SourceObject) && context.Element.GetInstance(animationReferenceSave.SourceObject) == null; ////////////////Early Out/////////////// if (isReferencingMissingInstance) { currentBlock.Line($"// This animation references a missing instance named {animationReferenceSave.SourceObject}"); return; } /////////////End Early Out///////////// string animationName = animationReferenceSave.PropertyNameInCode(); //animationReferenceSave. FlatRedBall.IO.FileManager.RemovePath(animationReferenceSave.Name) + "Animation"; if (absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } currentBlock.Line($"var instruction = new FlatRedBall.Instructions.DelegateInstruction(()=>{animationName}.Play({parentAnimation.PropertyNameInCode()}));"); currentBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + ToFloatString(animationReferenceSave.Time) + ";"); currentBlock.Line("yield return instruction;"); currentBlock = currentBlock.End(); }
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"); // Loop through states here and access properties that need the values foreach (StateSave state in list) { codeBlock = codeBlock.Case(variableType + "." + state.Name); 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(); 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///////////////////////////////////// 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; }
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; }
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(); } } } } }
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 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; }
public static void GetInitializationForReferencedFile(ReferencedFileSave referencedFile, IElement container, ICodeBlock codeBlock, bool loadsUsingGlobalContentManager, LoadType loadType) { #region early-outs (not loaded at runtime, loaded only when referenced) if (referencedFile.LoadedOnlyWhenReferenced) { return;// ""; } if (referencedFile.IsDatabaseForLocalizing == false && !referencedFile.GetGeneratesMember()) { return; // There is no qualified type to load to, so let's not generate code to load it } #endregion // I'm going to only do this if we're non-null so that we don't add it for global content. Global Content may load // async and cause bad data if (container != null) { PerformancePluginCodeGenerator.GenerateStart(container, codeBlock, "LoadStaticContent" + FileManager.RemovePath(referencedFile.Name)); } AddIfConditionalSymbolIfNecesssary(codeBlock, referencedFile); bool directives = false; for (int i = referencedFile.ProjectSpecificFiles.Count; i >= 0; i--) { bool isProjectSpecific = i != 0; string fileName; ProjectBase project; if (isProjectSpecific) { fileName = referencedFile.ProjectSpecificFiles[i - 1].FilePath.ToLower().Replace("\\", "/"); // At one point // the project specific // files were platform specific // but instead we want them to be // based off of the project name instead. // The reason for this is because a user could // create a synced project that targets the same // platform. project = ProjectManager.GetProjectByName(referencedFile.ProjectSpecificFiles[i - 1].ProjectId); if (project == null) { project = ProjectManager.GetProjectByTypeId(referencedFile.ProjectSpecificFiles[i - 1].ProjectId); } } else { fileName = referencedFile.Name.ToLower().Replace("\\", "/"); project = ProjectManager.ProjectBase; } string containerName = ContentLoadWriter.GlobalContentContainerName; if (container != null) { containerName = container.Name; } AddCodeforFileLoad(referencedFile, ref codeBlock, loadsUsingGlobalContentManager, ref directives, isProjectSpecific, ref fileName, project, loadType, containerName); } if (directives == true) { codeBlock = codeBlock.End() .Line("#endif"); } AddEndIfIfNecessary(codeBlock, referencedFile); // See above why this if-statement exists if (container != null) { PerformancePluginCodeGenerator.GenerateEnd(container, codeBlock, "LoadStaticContent" + FileManager.RemovePath(referencedFile.Name)); } }
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; }
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 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); } } }
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 void CreateInstructionForInterpolationRelative(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimatedStateSave previousState, AnimatedStateSave currentState) { if (previousState != null) { currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction(() =>"); { currentBlock = currentBlock.Block(); // Is the start clone necessary? currentBlock.Line("var relativeStart = ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + previousState.StateName + "\").Clone();"); currentBlock.Line("var relativeEnd = ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + currentState.StateName + "\").Clone();"); currentBlock.Line("Gum.DataTypes.Variables.StateSaveExtensionMethods.SubtractFromThis(relativeEnd, relativeStart);"); currentBlock.Line("var difference = relativeEnd;"); string categoryName = "VariableState"; var category = context.Element.Categories.FirstOrDefault(item => item.States.Any(stateCandidate => stateCandidate.Name == currentState.StateName)); string enumValue = currentState.StateName; if (currentState.StateName.Contains('/')) { var split = currentState.StateName.Split('/'); category = context.Element.Categories.FirstOrDefault(item => item.Name == split[0]); enumValue = split[1]; } if (category != null) { categoryName = category.Name; } currentBlock.Line("Gum.DataTypes.Variables.StateSave first = GetCurrentValuesOnState(" + categoryName + "." + enumValue + ");"); currentBlock.Line("Gum.DataTypes.Variables.StateSave second = first.Clone();"); currentBlock.Line("Gum.DataTypes.Variables.StateSaveExtensionMethods.AddIntoThis(second, difference);"); string interpolationTime = ToFloatString(currentState.Time - previousState.Time); string easing = "FlatRedBall.Glue.StateInterpolation.Easing." + previousState.Easing; string interpolationType = "FlatRedBall.Glue.StateInterpolation.InterpolationType." + previousState.InterpolationType; currentBlock.Line( string.Format("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from: 0, to: 1, duration: {0}, type: {1}, easing: {2});", interpolationTime, interpolationType, easing)); currentBlock.Line("tweener.Owner = this;"); currentBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(first, second, newPosition);"); currentBlock.Line("tweener.Start();"); currentBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); currentBlock = currentBlock.End(); } currentBlock.Line(");"); string previousStateTime = ToFloatString(previousState.Time); currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + previousStateTime + ";"); currentBlock.Line("toReturn.Target = target;"); currentBlock.Line("yield return toReturn;"); } }
private static void AddCodeforFileLoad(ReferencedFileSave referencedFile, ref ICodeBlock codeBlock, bool loadsUsingGlobalContentManager, ref bool directives, bool isProjectSpecific, ref string fileName, ProjectBase project, LoadType loadType, string containerName) { if (project != null) { if (ProjectManager.IsContent(fileName)) { fileName = (ProjectManager.ContentProject.ContainedFilePrefix + fileName).ToLower(); } if (isProjectSpecific) { if (directives == true) { codeBlock = codeBlock.End() .Line("#elif " + project.PrecompilerDirective) .CodeBlockIndented(); } else { directives = true; codeBlock = codeBlock .Line("#if " + project.PrecompilerDirective) .CodeBlockIndented(); } } else { if (directives == true) { codeBlock = codeBlock.End() .Line("#else") .CodeBlockIndented(); } } if (referencedFile.IsDatabaseForLocalizing) { GenerateCodeForLocalizationDatabase(referencedFile, codeBlock, fileName, loadType); } else { AssetTypeInfo ati = referencedFile.GetAssetTypeInfo(); // I think we can set the field rather than the property, and then Set() the MRE if necessary afterwards: //string variableName = referencedFile.GetInstanceName(); string variableName = null; if (NeedsFullProperty(referencedFile, containerName)) { variableName = "m" + referencedFile.GetInstanceName(); } else { variableName = referencedFile.GetInstanceName(); } if (!referencedFile.IsCsvOrTreatedAsCsv && ati != null) { // If it's not a CSV, then we only support loading if the load type is complete // I don't know if I'll want to change this (or if I can) in the future. if (loadType == LoadType.CompleteLoad) { GenerateInitializationForAssetTypeInfoRfs(referencedFile, codeBlock, loadsUsingGlobalContentManager, variableName, fileName, ati, project); } } else if(referencedFile.IsCsvOrTreatedAsCsv) { GenerateInitializationForCsvRfs(referencedFile, codeBlock, variableName, fileName, loadType); } } NamedObjectSaveCodeGenerator.WriteTextSpecificInitialization(referencedFile, codeBlock); } }
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); } } }
public static ICodeBlock FillWithCustomEventCode(ICodeBlock currentBlock, EventResponseSave ers, string contents, IElement element) { string args = ers.GetArgsForMethod(element); // We used to not // generate the empty // shell of an event if // the contents were empty. // However now we want to for // two reasons: // 1: A user may want to add an // event in Glue, but then mdoify // the event in Visual Studio. The // user shouldn't be forced into adding // some content in Glue first to wdit the // event in Visual Studio. // 2: A designer may decide to remove the // contents of a method. If this happens then // code that the designer doesn't work with shouldn't // break (IE, if the code calls the OnXXXX method). //if (!string.IsNullOrEmpty(contents)) { // Need to modify the event CSV to include the arguments for this event currentBlock = currentBlock .Function("void", "On" + ers.EventName, args); currentBlock.TabCharacter = ""; int tabCount = currentBlock.TabCount; currentBlock.TabCount = 0; currentBlock .Line(contents); currentBlock = currentBlock.End(); } return currentBlock; }
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 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(); } } } } }
private static ICodeBlock GetInitializeFactoryMethod(ICodeBlock codeBlock, string className, bool poolObjects, string listToAssign) { codeBlock = codeBlock .Function("public static void", "Initialize", string.Format("FlatRedBall.Math.PositionedObjectList<{0}> listFromScreen, string contentManager", className)) .Line("mContentManagerName = contentManager;") .Line(listToAssign + " = listFromScreen;"); if (poolObjects) { codeBlock.Line("FactoryInitialize();"); } codeBlock = codeBlock.End(); 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 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 CreateInstructionForSubAnimation(ICodeBlock currentBlock, AnimationReferenceSave animationReferenceSave, AbsoluteOrRelative absoluteOrRelative, AnimationSave parentAnimation) { currentBlock = currentBlock.Block(); //var instruction = new FlatRedBall.Instructions.DelegateInstruction(() => //FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(ClickableBushInstance.GrowAnimation)); //instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + asdf; //yield return instruction; string animationName = animationReferenceSave.PropertyNameInCode(); //animationReferenceSave. FlatRedBall.IO.FileManager.RemovePath(animationReferenceSave.Name) + "Animation"; if(absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } currentBlock.Line($"var instruction = new FlatRedBall.Instructions.DelegateInstruction(()=>{animationName}.Play({parentAnimation.PropertyNameInCode()}));"); currentBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + ToFloatString(animationReferenceSave.Time) + ";"); currentBlock.Line("yield return instruction;"); currentBlock = currentBlock.End(); }
public override ICodeBlock GenerateAdditionalMethods(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); string visibleSettingLine = ""; if (entitySave.ImplementsIVisible) { visibleSettingLine = "newItem.Visible = this.Visible;"; } #region AddItemToTop codeBlock .Function("void", "AddItemToTop", "") .Line(string.Format("{0} newItem = Factories.{0}Factory.CreateNew(LayerProvidedByContainer);", itemTypeWithoutPath)) .Line(visibleSettingLine) .Line("mLastCreatedScrollableItem = newItem;") .Line("newItem.AttachTo(mScrollableHandle, false);") .If("mScrollableItems.Count > 0") .Line("newItem.RelativeY = mScrollableItems[0].RelativeY + mScrollableSpacing;") .End() .Line("newItem.ForceUpdateDependencies();") .Line("mScrollableFirstIndex--;") .Line("mScrollableItems.Insert(0, newItem);") .If("ScrollItemModified != null") .Line("ScrollItemModified(newItem);") .End() .Line("mLastCreatedScrollableItem = null;") .End() #endregion #region AddItemToBottom .Function("void", "AddItemToBottom", "") .Line(string.Format("{0} newItem = Factories.{0}Factory.CreateNew(LayerProvidedByContainer);", itemTypeWithoutPath)) .Line("mLastCreatedScrollableItem = newItem;") .Line("newItem.AttachTo(mScrollableHandle, false);") .If("mScrollableItems.Count > 0") .Line("newItem.RelativeY = mScrollableItems.Last.RelativeY - mScrollableSpacing;") .End() .Else() .Line("newItem.RelativeY = 0;") .End() .Line("newItem.ForceUpdateDependencies();") .Line("mScrollableItems.Add(newItem);") .If("ScrollItemModified != null") .Line("ScrollItemModified(newItem);") .End() .Line("mLastCreatedScrollableItem = null;") .End(); #endregion codeBlock = codeBlock.Function("void", "ScrollableListActivity", ""); var curBlock = codeBlock .If("ListShowing != null") .Line("FlatRedBall.Gui.Cursor cursor = FlatRedBall.Gui.GuiManager.Cursor;"); if (entitySave.ImplementsIClickable || entitySave.ImplementsIWindow || entitySave.GetInheritsFromIWindowOrIClickable()) { curBlock = curBlock.If("cursor.PrimaryDown && HasCursorOver(GuiManager.Cursor)"); } else { curBlock = curBlock.If("cursor.PrimaryDown"); } curBlock = curBlock .Line("mScrollableHandle.RelativeY += FlatRedBall.Gui.GuiManager.Cursor.WorldYChangeAt(this.Z, LayerProvidedByContainer);") .Line("FixScrollableHandleRelativeY();") .Line("mScrollableHandle.ForceUpdateDependenciesDeep();") .End(); curBlock .Line("PerformScrollableItemAdditionLogic();") .Line("// remove from top") .While("mScrollableItems.Count > 2 && mScrollableItems[1].Y > mScrollableTopBoundary") .Line("RemoveItemFromTop();") .End() .Line("// remove from bottom") .While("mScrollableItems.Count > 2 && mScrollableItems[mScrollableItems.Count - 2].Y < mScrollableBottomBoundary") .Line("RemoveItemFromBottom();") .End() .Line("bool shouldRefreshAll = false;") .While("ListShowing.Count < mScrollableItems.Count") .Line("RemoveItemFromBottom();") .Line("shouldRefreshAll = true;") .End() .If("shouldRefreshAll") .Line("RefreshAllScrollableListItems();") .End(); codeBlock .Else() .While("mScrollableItems.Count > 0") .Line("mScrollableItems.Last.Destroy();"); codeBlock = codeBlock.End(); codeBlock.Function("public bool", "IsScrollableItemNew", string.Format("{0} itemInQuestion", itemTypeWithoutPath)) .Line("return itemInQuestion == mLastCreatedScrollableItem;") .End() .Function("void", "RemoveItemFromTop", "") .Line("mScrollableItems[0].Destroy();") .Line("mScrollableFirstIndex++;") .End() .Function("void", "RemoveItemFromBottom", "") .Line("mScrollableItems.Last.Destroy();") .End() .Function("public int", "GetAbsoluteIndexForItem", itemTypeWithoutPath + " item") .Line("int indexInList = mScrollableItems.IndexOf(item);") .Line("return mScrollableFirstIndex + indexInList;") .End() .Property("public bool", "IsAtTop") .Get() .Line("return mScrollableFirstIndex == 0;") .End() .End() .Function("RefreshAllScrollableListItems", "", Type:"void") .If("mListShowingButUsePropertyPlease == null") .While("mScrollableItems.Count > 0") .Line("mScrollableItems.Last.Destroy();") .End() .End() .Else() .For("int i = 0; i < mScrollableItems.Count; i++") .If("ScrollItemModified != null") .Line("ScrollItemModified(mScrollableItems[i]);") .End() .End() .End() .End() .Function("RefreshToList", "", Type:"void", Public:true) .Line("PerformScrollableItemAdditionLogic();") .While("mScrollableItems.Count > 2 && mScrollableItems[1].Y > mScrollableTopBoundary") .Line("RemoveItemFromTop();") .End() .While("mScrollableItems.Count > 2 && mScrollableItems[mScrollableItems.Count - 2].Y < mScrollableBottomBoundary || ListShowing.Count < mScrollableItems.Count") .Line("RemoveItemFromBottom();") .End() .Line("RefreshAllScrollableListItems();") .End() .Function("void", "FixScrollableHandleRelativeY", "") .Line("mScrollableHandle.RelativeY = System.Math.Min(mScrollableHandle.RelativeY,(ListShowing.Count - 1) * mScrollableSpacing + mScrollableBottomBoundary);") .Line("mScrollableHandle.RelativeY = System.Math.Max(mScrollableHandle.RelativeY, " + entitySave.ListTopBound + ");") .End() .Function("void", "PerformScrollableItemAdditionLogic", "") .Line("// add to bottom") .While("mScrollableFirstIndex + mScrollableItems.Count < ListShowing.Count && (mScrollableItems.Count == 0 || mScrollableItems.Last.Y > mScrollableBottomBoundary)") .Line("AddItemToBottom();") .End() .Line("// add to top") .While("mScrollableFirstIndex > 0 && mScrollableItems.Count < ListShowing.Count && (mScrollableItems.Count == 0 || mScrollableItems[0].Y < mScrollableTopBoundary)") .Line("AddItemToTop();") .End() .End(); } } return codeBlock; }
private void CreateInstructionForInterpolation(StateCodeGeneratorContext context, ICodeBlock currentBlock, string animationType, AnimatedStateSave previousState, AnimatedStateSave currentState, AbsoluteOrRelative absoluteOrRelative, string animationName) { currentBlock = currentBlock.Block(); if (absoluteOrRelative == AbsoluteOrRelative.Absolute) { CreateInstructionForInterpolationAbsolute(context, currentBlock, animationType, previousState, currentState, animationName); } else { CreateInstructionForInterpolationRelative(context,currentBlock, previousState, currentState); } currentBlock = currentBlock.End(); }
private static ICodeBlock AppendEnum(ICodeBlock currentBlock, List<StateSave> statesForThisCategory, string enumName, IElement element) { if (statesForThisCategory.Count != 0) { string prefix = "public"; if (ShouldUseNewKeyword(element, enumName)) { prefix += " new"; } currentBlock = currentBlock .Enum(prefix, enumName) .Line("Uninitialized = 0, //This exists so that the first set call actually does something") .Line("Unknown = 1, //This exists so that if the entity is actually a child entity and has set a child state, you will get this"); for (int i = 0; i < statesForThisCategory.Count; i++) { string whatToAppend = ""; if (i != statesForThisCategory.Count - 1) { whatToAppend += ", "; } currentBlock.Line(statesForThisCategory[i].Name + " = " + (i + 2) + whatToAppend); } currentBlock = currentBlock.End(); } return currentBlock; }
private void CreateInstructionForInterpolationRelative(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimatedStateSave previousState, AnimatedStateSave currentState) { if(previousState != null) { currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction(() =>"); { currentBlock = currentBlock.Block(); // Is the start clone necessary? currentBlock.Line("var relativeStart = ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + previousState.StateName + "\").Clone();"); currentBlock.Line("var relativeEnd = ElementSave.AllStates.FirstOrDefault(item => item.Name == \"" + currentState.StateName + "\").Clone();"); currentBlock.Line("Gum.DataTypes.Variables.StateSaveExtensionMethods.SubtractFromThis(relativeEnd, relativeStart);"); currentBlock.Line("var difference = relativeEnd;"); string categoryName = "VariableState"; var category = context.Element.Categories.FirstOrDefault(item => item.States.Any(stateCandidate => stateCandidate.Name == currentState.StateName)); string enumValue = currentState.StateName; if(currentState.StateName.Contains('/')) { var split = currentState.StateName.Split('/'); category = context.Element.Categories.FirstOrDefault(item => item.Name == split[0]); enumValue = split[1]; } if(category != null) { categoryName = category.Name; } currentBlock.Line("Gum.DataTypes.Variables.StateSave first = GetCurrentValuesOnState(" + categoryName + "." + enumValue + ");"); currentBlock.Line("Gum.DataTypes.Variables.StateSave second = first.Clone();"); currentBlock.Line("Gum.DataTypes.Variables.StateSaveExtensionMethods.AddIntoThis(second, difference);"); string interpolationTime = ToFloatString(currentState.Time - previousState.Time); string easing = "FlatRedBall.Glue.StateInterpolation.Easing." + previousState.Easing; string interpolationType = "FlatRedBall.Glue.StateInterpolation.InterpolationType." + previousState.InterpolationType; currentBlock.Line( string.Format("FlatRedBall.Glue.StateInterpolation.Tweener tweener = new FlatRedBall.Glue.StateInterpolation.Tweener(from: 0, to: 1, duration: {0}, type: {1}, easing: {2});", interpolationTime, interpolationType, easing)); currentBlock.Line("tweener.Owner = this;"); currentBlock.Line("tweener.PositionChanged = newPosition => this.InterpolateBetween(first, second, newPosition);"); currentBlock.Line("tweener.Start();"); currentBlock.Line("StateInterpolationPlugin.TweenerManager.Self.Add(tweener);"); currentBlock = currentBlock.End(); } currentBlock.Line(");"); string previousStateTime = ToFloatString(previousState.Time); currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + previousStateTime + ";"); currentBlock.Line("yield return toReturn;"); } }
private void GenerateGetEnumerableFor(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. const string signature = "private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>"; if (animation.States.Count == 0 && animation.Animations.Count == 0) { currentBlock = currentBlock.Function(signature, propertyName, "object target"); currentBlock.Line("yield break;"); } else if (absoluteOrRelative == AbsoluteOrRelative.Relative && animation.States.Count < 2 && animation.Animations.Count == 0) { currentBlock = currentBlock.Function(signature, propertyName, "object target"); 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.Function(signature, propertyName, "object target"); 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 + "(target)));"); 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("toReturn.Target = target;"); currentBlock.Line("yield return toReturn;"); currentBlock = currentBlock.End(); } } }
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; }
public override ICodeBlock GenerateAdditionalMethods(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); string visibleSettingLine = ""; if (entitySave.ImplementsIVisible) { visibleSettingLine = "newItem.Visible = this.Visible;"; } #region AddItemToTop codeBlock .Function("void", "AddItemToTop", "") .Line(string.Format("{0} newItem = Factories.{0}Factory.CreateNew(LayerProvidedByContainer);", itemTypeWithoutPath)) .Line(visibleSettingLine) .Line("mLastCreatedScrollableItem = newItem;") .Line("newItem.AttachTo(mScrollableHandle, false);") .If("mScrollableItems.Count > 0") .Line("newItem.RelativeY = mScrollableItems[0].RelativeY + mScrollableSpacing;") .End() .Line("newItem.ForceUpdateDependencies();") .Line("mScrollableFirstIndex--;") .Line("mScrollableItems.Insert(0, newItem);") .If("ScrollItemModified != null") .Line("ScrollItemModified(newItem);") .End() .Line("mLastCreatedScrollableItem = null;") .End() #endregion #region AddItemToBottom .Function("void", "AddItemToBottom", "") .Line(string.Format("{0} newItem = Factories.{0}Factory.CreateNew(LayerProvidedByContainer);", itemTypeWithoutPath)) .Line("mLastCreatedScrollableItem = newItem;") .Line("newItem.AttachTo(mScrollableHandle, false);") .If("mScrollableItems.Count > 0") .Line("newItem.RelativeY = mScrollableItems.Last.RelativeY - mScrollableSpacing;") .End() .Else() .Line("newItem.RelativeY = 0;") .End() .Line("newItem.ForceUpdateDependencies();") .Line("mScrollableItems.Add(newItem);") .If("ScrollItemModified != null") .Line("ScrollItemModified(newItem);") .End() .Line("mLastCreatedScrollableItem = null;") .End(); #endregion codeBlock = codeBlock.Function("void", "ScrollableListActivity", ""); var curBlock = codeBlock .If("ListShowing != null") .Line("FlatRedBall.Gui.Cursor cursor = FlatRedBall.Gui.GuiManager.Cursor;"); if (entitySave.ImplementsIClickable || entitySave.ImplementsIWindow || entitySave.GetInheritsFromIWindowOrIClickable()) { curBlock = curBlock.If("cursor.PrimaryDown && HasCursorOver(GuiManager.Cursor)"); } else { curBlock = curBlock.If("cursor.PrimaryDown"); } curBlock = curBlock .Line("mScrollableHandle.RelativeY += FlatRedBall.Gui.GuiManager.Cursor.WorldYChangeAt(this.Z, LayerProvidedByContainer);") .Line("FixScrollableHandleRelativeY();") .Line("mScrollableHandle.ForceUpdateDependenciesDeep();") .End(); curBlock .Line("PerformScrollableItemAdditionLogic();") .Line("// remove from top") .While("mScrollableItems.Count > 2 && mScrollableItems[1].Y > mScrollableTopBoundary") .Line("RemoveItemFromTop();") .End() .Line("// remove from bottom") .While("mScrollableItems.Count > 2 && mScrollableItems[mScrollableItems.Count - 2].Y < mScrollableBottomBoundary") .Line("RemoveItemFromBottom();") .End() .Line("bool shouldRefreshAll = false;") .While("ListShowing.Count < mScrollableItems.Count") .Line("RemoveItemFromBottom();") .Line("shouldRefreshAll = true;") .End() .If("shouldRefreshAll") .Line("RefreshAllScrollableListItems();") .End(); codeBlock .Else() .While("mScrollableItems.Count > 0") .Line("mScrollableItems.Last.Destroy();"); codeBlock = codeBlock.End(); codeBlock.Function("public bool", "IsScrollableItemNew", string.Format("{0} itemInQuestion", itemTypeWithoutPath)) .Line("return itemInQuestion == mLastCreatedScrollableItem;") .End() .Function("void", "RemoveItemFromTop", "") .Line("mScrollableItems[0].Destroy();") .Line("mScrollableFirstIndex++;") .End() .Function("void", "RemoveItemFromBottom", "") .Line("mScrollableItems.Last.Destroy();") .End() .Function("public int", "GetAbsoluteIndexForItem", itemTypeWithoutPath + " item") .Line("int indexInList = mScrollableItems.IndexOf(item);") .Line("return mScrollableFirstIndex + indexInList;") .End() .Property("public bool", "IsAtTop") .Get() .Line("return mScrollableFirstIndex == 0;") .End() .End() .Function("RefreshAllScrollableListItems", "", Type: "void") .If("mListShowingButUsePropertyPlease == null") .While("mScrollableItems.Count > 0") .Line("mScrollableItems.Last.Destroy();") .End() .End() .Else() .For("int i = 0; i < mScrollableItems.Count; i++") .If("ScrollItemModified != null") .Line("ScrollItemModified(mScrollableItems[i]);") .End() .End() .End() .End() .Function("RefreshToList", "", Type: "void", Public: true) .Line("PerformScrollableItemAdditionLogic();") .While("mScrollableItems.Count > 2 && mScrollableItems[1].Y > mScrollableTopBoundary") .Line("RemoveItemFromTop();") .End() .While("mScrollableItems.Count > 2 && mScrollableItems[mScrollableItems.Count - 2].Y < mScrollableBottomBoundary || ListShowing.Count < mScrollableItems.Count") .Line("RemoveItemFromBottom();") .End() .Line("RefreshAllScrollableListItems();") .End() .Function("void", "FixScrollableHandleRelativeY", "") .Line("mScrollableHandle.RelativeY = System.Math.Min(mScrollableHandle.RelativeY,(ListShowing.Count - 1) * mScrollableSpacing + mScrollableBottomBoundary);") .Line("mScrollableHandle.RelativeY = System.Math.Max(mScrollableHandle.RelativeY, " + entitySave.ListTopBound + ");") .End() .Function("void", "PerformScrollableItemAdditionLogic", "") .Line("// add to bottom") .While("mScrollableFirstIndex + mScrollableItems.Count < ListShowing.Count && (mScrollableItems.Count == 0 || mScrollableItems.Last.Y > mScrollableBottomBoundary)") .Line("AddItemToBottom();") .End() .Line("// add to top") .While("mScrollableFirstIndex > 0 && mScrollableItems.Count < ListShowing.Count && (mScrollableItems.Count == 0 || mScrollableItems[0].Y < mScrollableTopBoundary)") .Line("AddItemToTop();") .End() .End(); } } return(codeBlock); }
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 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 ICodeBlock CreateClassForStateCategory(ICodeBlock currentBlock, List <StateSave> statesForThisCategory, string categoryClassName, IElement element) { if (statesForThisCategory.Count != 0) { string prefix = "public"; string postfix = null; if (IsStateDefinedInBase(element, categoryClassName)) { postfix = $" : {element.BaseElement.Replace("\\", ".")}.{categoryClassName}"; } currentBlock = currentBlock.Class(prefix, categoryClassName, postfix); currentBlock.Line($"public string Name;"); foreach (var variable in element.CustomVariables) { // todo - pass the category here and skip over excluded variables var isExcluded = false; if (!isExcluded) { string type = variable.Type; if (variable.GetIsFile()) { type = "string"; } else { type = CustomVariableCodeGenerator.GetMemberTypeFor(variable, element); } currentBlock.Line($"public {type} {variable.Name};"); } } for (int i = 0; i < statesForThisCategory.Count; i++) { var state = statesForThisCategory[i]; currentBlock.Line($"public static {categoryClassName} {state.Name} = new {categoryClassName}()"); var variableBlock = currentBlock.Block(); variableBlock.Line($"Name = \"{state.Name}\","); foreach (var instruction in state.InstructionSaves) { if (instruction.Value != null) { var rightSide = GetRightSideAssignmentValueAsString(element, instruction); var matchingVariable = element.GetCustomVariableRecursively(instruction.Member); if (matchingVariable?.GetIsFile() == true) { // If it's a file we are only going to reference the file name here as to not preload the file rightSide = $"\"{rightSide}\""; } variableBlock.Line($"{instruction.Member} = {rightSide},"); } } variableBlock.End().Line(";"); } currentBlock = currentBlock.End(); } return(currentBlock); }
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, VariableNamesToReplaceForStates); if (GetValue(mInterpolationCharacteristics, nameInCode, element) != InterpolationCharacteristic.CantInterpolate) { string stringSuffix = variable.MemberNameInCode(element, VariableNamesToReplaceForStates).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, VariableNamesToReplaceForStates).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 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); }
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("var layerToRemoveFrom = LayerProvidedByContainer; // assign before calling base so removal is not impacted by base call"); codeBlock.Line("base.MoveToLayer(layerToMoveTo);"); } else { codeBlock = codeBlock.Function("public virtual void", "MoveToLayer", "FlatRedBall.Graphics.Layer layerToMoveTo"); codeBlock.Line("var layerToRemoveFrom = LayerProvidedByContainer;"); } if (element.InheritsFromFrbType()) { AssetTypeInfo ati = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(element.BaseElement, element); if (ati != null) { if (ati.RemoveFromLayerMethod != null) { codeBlock.If("layerToRemoveFrom != null") .Line(ati.RemoveFromLayerMethod.Replace("mLayer", "layerToRemoveFrom") + ";") .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 && !nos.DefinedByBase) { 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("layerToRemoveFrom != null") .Line(nos.GetAssetTypeInfo().RemoveFromLayerMethod.Replace("this", nos.InstanceName).Replace("mLayer", "layerToRemoveFrom") + ";") .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(); } } } } if (isInDerived == false) { // Doesn't hurt if derived assigns this but...I guess we can keep it clean and only do it in one place codeBlock.Line("LayerProvidedByContainer = layerToMoveTo;"); } codeBlock = codeBlock.End(); return(codeBlock); }