Correctly load level without modifying the original - object

Currently, my game works like this :
public class TheGame: Microsoft.Xna.Framework.Game
{
public static Level CurrentLevel;
private Level level1, level2, level3;
protected override void LoadContent()
{
level1 = new Level(//param);
level2 = new Level(//param);
level3 = new Level(//param);
}
protected override void Update(GameTime gameTime)
{
If(something)
LoadLevel(level1);
currentLevel.Update(gameTime);
//
}
LoadLevel(Level theLevel)
{
currentLevel = theLevel;
}
}
The problem is, when i modify the currentLevel with an Update(), that modifies Level1 too.
For example :
Level1 has a crate with position (100,200).
if currentLevel.Update() modifies the crate's position (120,200),
that modifies the crate's position in CurrentLevel AND the crate's position in Level1.
So when i reload Level1, the level is different from the original level1.
Is it because of Static ? because i have to clone Level1 ? Something else ? :s
Thx for reading.

You are always loading the same variable, since you store level1, level2 and level3 as instance variables of your main Game class and assign them to currentLevel in an instance method. The static modifier has nothing to do with it.
Instead, you should reload the level each time or rebuild it from whatever data you have loaded. Another option is having a method which restores it to its original state, but this requires that everything in the level can be reverted to a known initial state. Usually, simply reloading assets or cloning them is easier.

Related

Unity - Detecting keyboard input

I'm fairly new to Unity and have been looking up tons of tutorials/guides online. My issue is that for some reason when I use the below code it doesn't detect if the keyboard is clicked. Maybe I am doing keyboard detection wrong. Here is my code:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
Vector3 player = GameObject.FindGameObjectWithTag("Player").transform.position;
void Update () {
if (Input.GetKeyDown(KeyCode.D)) {
player.x += 0.01F;
}
}
}
Your input code is correct but still couple of things that are not at right place. First you wrote an initializer (static method) outside any function. Remember when you do it in Unity3d C# then it will always give you a warning/error.
If you are using C# don't use this function in the constructor or field initializers, Instead move initialization to the Awake or Start function.
So first move that sort of lines in either functions.
Second thing you are getting Vector3 and trying to use it as reference, that means you got a position reference in form of Vector3 and every change made in that variable will be effective, that is not the case, it won't.
But yes you can do it by getting Transform or GameObject, they will do it for you.
Third and last thing, you are trying to alter Vector3 component ("x" in your case ) directly, that'd also not acceptable for Unity. What you can do is either assign position with new Vector3 or create a separate Vector3 variable, alter that, then assign it to position.
So after all of these addresses your code should be look like this,
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour
{
Transform player;
// Use this for initialization
void Start ()
{
player = GameObject.FindGameObjectWithTag ("Player").transform;
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown (KeyCode.D)) {
// Remove one of these two implementations of changing position
// Either
Vector3 newPosition = player.position;
newPosition.x += 0.01f;
player.position = newPosition;
//Or
player.position = new Vector3 (player.position.x + 0.01f, player.position.y, player.position.z);
}
}
}

How do I add to a GLib.List from different Thread in Vala

I have a GLib.List to which I want to add elements.
I want to add those elements concurrently using multiple GLib.Threads
I'm trying to synchronize access to the list using a GLib.Mutex. Synchronization seems to work but no elements are added.
public static void main() {
var list = new GLib.List<string>();
var mutex = GLib.Mutex();
var workerA = new Worker("A", list, mutex);
var workerB = new Worker("B", list, mutex);
var workerC = new Worker("C", list, mutex);
GLib.Thread<void*> tA = new GLib.Thread<void*>("WorkerThread", workerA.run);
GLib.Thread<void*> tB = new GLib.Thread<void*>("WorkerThread", workerB.run);
GLib.Thread<void*> tC = new GLib.Thread<void*>("WorkerThread", workerC.run);
tA.join();
tB.join();
tC.join();
stdout.printf("List:\n");
foreach (string str in list) {
stdout.printf(" - %s\n", str);
}
}
class Worker : GLib.Object {
private string name;
private weak GLib.List<string> list;
private weak GLib.Mutex mutex;
public Worker(string name, GLib.List<string> list, GLib.Mutex mutex) {
this.name = name;
this.list = list;
this.mutex = mutex;
}
public void* run() {
mutex.lock();
list.append(name);
mutex.unlock();
return null;
}
}
When I look at the synchronization part it seems to work right (even with many more Threads), but no elements get added to the list!
Output:
List:
Can somebody please tell me how to do this ?
GLib.List is a little weird. The append method actually modifies the pointer list, not the thing it is pointing to. If you want this to work you need to either:
Put the list in a shared place (e.g., make it a field of a class that all the threads share or a global variable).
Use Gee.List from the libgee package instead. In general, the data structures in libgee are much easier to use in Vala than their counter parts in glib.
Thanks to apmasell pointing out the thing not working is actually GLib.List I took a look at the C source code.
He's right: The append method modifies the pointer - but only (!) if the GLib.List is empty!
So Apart from making the list a global variable or using another list implementation I think the best work workaround is to simply add one element before passing the list to a thread.
After all threads are done you can simply remove the element again.

When are child views added to Layout/ViewGroup from XML

My question is :
I want to know when does a xLayout (or ViewGroup in general) add a child view from XML ? And by "when" I mean at what point of code, in what "pass" of the "traversal" of the UI toolkit ?
Which method of xLayout or ViewGroup should I override ?
I have done my homework : I have watched the "Writing Custom Views For Android" presented (by Adam Powell and Romain Guy) in the last Google I/O and I have read Adam Powell comments on this Google+ post.
Looking for the exact point in Android's source code where children are added.
We can look at what setContentView(R.layout.some_id) is doing under the hood.
setContentView(int) calls PhoneWindow#setContentView(int) - PhoneWindowLink is a concrete inplementation of Window:
#Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mLayoutInflater.inflate(layoutResID, mContentParent);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
The method LayoutInflater#inflate(layoutResID, mContentParent) eventually calls ViewGroup#addView(View, LayoutParams) on mContentParent. In between, child views
I want to know what happens exactly after I set content view to an XML file that contains a custom view. Afer the constructor there has to be a part in the code where the custom view "parse/read/inflate/convert" XML-declared child views to actual views ! (comment by JohnTube)
Ambiquity: From JohnTube's comment, it seems he is more interested in knowing how a custom view is inflated. To know this, we will have to look at the workings of LayoutInflaterLink.
So, the answer to Which method of xLayout or ViewGroup should I override ? is ViewGroup#addView(View, LayoutParams). Note that, at this point, the inflation of all regular/custom Views has already taken place.
Inflation of custom views:
The following method in LayoutInflater is where the addView(View, LayoutParams) is called on the parent/root:
Note: The call mLayoutInflater.inflate(layoutResID, mContentParent); in PhoneWindow#setContentView(int) chains to this. Here mContentParent is the DecorView: the view that's accessible through getWindow().getDecorView().
// Inflate a new view hierarchy from the specified XML node.
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
// Recursive method used to descend down the xml hierarchy and instantiate views,
// instantiate their children, and then call onFinishInflate().
void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
boolean finishInflate) throws XmlPullParserException, IOException
The call of interest in this method(and in the recursive rInflate(XmlPullParser, View, AttributeSet, boolean)) is:
temp = createViewFromTag(root, name, attrs);
Let's see what createViewFromTag(...) is doing:
View createViewFromTag(View parent, String name, AttributeSet attrs) {
....
....
if (view == null) {
if (-1 == name.indexOf('.')) {
view = onCreateView(parent, name, attrs);
} else {
view = createView(name, null, attrs);
}
}
....
}
The period(.) decides whether onCreateView(...) or createView(...) is called.
Why this check? Because a View defined in android.view, android.widget or android.webkit package is accessed through its class name. For example:
android.widget: Button, TextView etc.
android.view: ViewStub. SurfaceView, TextureView etc.
android.webkit: WebView
When these views are encountered, onCreateView(parent, name, attrs) is called. This method actually chains to createView(...):
protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
return createView(name, "android.view.", attrs);
}
This would deal with SurfaceView, TextureView and other views defined in android.view package. If you are interested in knowing how TextView, Button etc. are dealt with, look at PhoneLayoutInflaterLink - it extends LayoutInflater and overrides onCreateView(...) to check if android.widget and android.webkit are the intended package names. In fact, the call getLayoutInflater() gets you an instance of PhoneLayoutInflater. This is why if you were to subclass LayoutInflater, you couldn't even inflate the simplest of layouts - because LayoutInflater can only deal with views from android.view package.
Anyway, I digress. This extra bit happens for regular Views - which don't have a period(.) in their definition. Custom views do have a period in their names - com.my.package.CustomView. This is how the LayoutInflater distinguishes between the two.
So, in case of a regular view(say, Button), a prefix such as android.widget will be passed as the second argument - for custom views, this will be null. The prefix is then used along with the name to obtain the constructor for that particular view's class. Custom views don't need this because their name is already fully qualified. I guess this has been done for convenience. Else, you would have been defining your layouts in this way:
<android.widget.LinearLayout
...
... />
(Its legal though...)
Also, this is why views coming from a support library (eg. <android.support.v4.widget.DrawerLayout.../>) have to use fully qualified names.
By the way, if you did want to write your layouts as:
<MyCustomView ../>
all you have to do is to extend LayoutInflater and add your package name com.my.package. to the list of strings that are checked during inflation. Check PhoneLayoutInflater for help with this.
Let's see what happens in the final stage for both custom and regular views - createView(...):
public final View createView(String name, String prefix, AttributeSet attrs)
throws ClassNotFoundException, InflateException {
// Try looking for the constructor in cache
Constructor<? extends View> constructor = sConstructorMap.get(name);
Class<? extends View> clazz = null;
try {
if (constructor == null) {
// Class not found in the cache, see if it's real, and try to add it
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
....
// Get constructor
constructor = clazz.getConstructor(mConstructorSignature);
sConstructorMap.put(name, constructor);
} else {
....
}
Object[] args = mConstructorArgs;
args[1] = attrs;
// Obtain an instance
final View view = constructor.newInstance(args);
....
// We finally have a view!
return view;
}
// A bunch of catch blocks:
- if the only constructor defined is `CustomView(Context)` - NoSuchMethodException
- if `com.my.package.CustomView` doesn't extend View - ClassCastException
- if `com.my.package.CustomView` is not found - ClassNotFoundException
// All these catch blocks throw the often seen `InflateException`.
}
... a View is born.
If you're talking about a ViewGroup defined in XML, it's children are added when the view is inflated. This can be when you inflate explicitly with a LayoutInflater or when you set the content view of an activity. (There are probably a few other times as well, particularly if you are using stub views.)
If you want to add the children yourself to a ViewGroup that is not inflated, you can do that in the view's constructor.
EDIT: If you want to see how the children are added when a view is inflated, this occurs in the call to LayoutInflater.inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot). The source for android.view.LayoutInflater is included in the Android SDK distributions; on-line versions can be found in many places (here at GrepCode, for instance). This method ends up being called when, for instance, you call setContentView(int) for an Activity or when you explicitly inflate a layout resource.
The children are actually added in the call to rInflate(parser, root, attrs, false); ("recursive inflate"), which might be called from a couple of different places in the inflate() method, depending on what the inflater found as the root tag. You can trace through the code logic yourself. An interesting point is that a child is not added to its parent until its own children have been recursively inflated and added to it.
The other interesting method, used by both inflate and rInflate, is createViewFromTag. This might rely on an installable LayoutInflater.Factory (or .Factory2 object) to create the view, or may end up calling createView. There you can see how the call to the view's two-argument constructor ((Context context, AttributeSet attrs)) is made.

Can I use something like DebuggerTypeProxyAttribute on a type that I don't own?

I've got an IClaimsPrincipal variable, and I'd like to see how many claims are in it. Navigating through the properties in the watch window is complicated, so I'd like to customize how this object is displayed.
I'm aware of the [DebuggerTypeProxy] attribute, which initially looked like it might do what I want. Unfortunately, it needs to be attached to the class, and I don't "own" the class. In this case it's a Microsoft.IdentityModel.Claims.ClaimsPrincipal.
I'd like to display the value of IClaimsPrincipal.Identities[0].Claims.Count.
Is there any way, using [DebuggerTypeProxy] or similar, to customize how the value of a type that I don't own is displayed in the watch window?
Example of DebuggerTypeProxyAttribute applied to KeyValuePair showing only the Value member:
using System.Collections.Generic;
using System.Diagnostics;
[assembly: DebuggerTypeProxy(typeof(ConsoleApp2.KeyValuePairDebuggerTypeProxy<,>), Target = typeof(KeyValuePair<,>))]
// alternative format [assembly: DebuggerTypeProxy(typeof(ConsoleApp2.KeyValuePairDebuggerTypeProxy<,>), TargetTypeName = "System.Collections.Generic.KeyValuePair`2")]
namespace ConsoleApp2
{
class KeyValuePairDebuggerTypeProxy<TKey, TValue>
{
private KeyValuePair<TKey, TValue> _keyValuePair; // beeing non-public this member is hidden
//public TKey Key => _keyValuePair.Key;
public TValue Value => _keyValuePair.Value;
public KeyValuePairDebuggerTypeProxy(KeyValuePair<TKey, TValue> keyValuePair)
{
_keyValuePair = keyValuePair;
}
}
class Program
{
static void Main(string[] args)
{
var dictionary = new Dictionary<int, string>() { [1] = "one", [2] = "two" };
Debugger.Break();
}
}
}
Tested on Visual Studio 2017
The best I've come up with so far is to call a method:
public static class DebuggerDisplays
{
public static int ClaimsPrincipal(IClaimsPrincipal claimsPrincipal)
{
return claimsPrincipal.Identities[0].Claims.Count;
}
}
...from the watch window:
DebuggerDisplays.ClaimsPrincipal(_thePrincipal),ac = 10
The ",ac" suppresses the "This expression causes side effects and will not be evaluated".
However, note that when this goes out of scope, Visual Studio will simply grey out the watch window entry, even with the ",ac". To avoid this, you'll need to ensure that everything is fully qualified, which means that you'll end up with extremely long expressions in the watch window.

How to force the order of Installer Execution

I have been building a new .NET solu­tion with Cas­tle per­form­ing my DI.
Its now at the stage where i would like to con­trol the order in which my installers run. I have built indi­vid­ual classes which implement IWind­sorIn­staller to han­dle my core types — eg IRepos­i­tory, IMap­per and ISer­vice to name a few.
I see that its suggested i implement my own Installer­Fac­tory (guessing i just override Select) in this class.
Then use this new factory in my call to:
FromAssembly.InDirectory(new AssemblyFilter("bin loca­tion"));
My ques­tion — when over­rid­ing the save method — what is the best way to force the order of my installers.
I know its already solved but I couldn't find any example on how to actually implement the InstallerFactory so here's a solution if anyone is googling for it.
How to use:
[InstallerPriority(0)]
public class ImportantInstallerToRunFirst : IWindsorInstaller
{
public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
// do registrations
}
}
Just add the InstallerPriority attribute with a priority to your "install-order-sensitive" classes. Installers will be sorted by ascending. Installers without priority will default to 100.
How to implement:
public class WindsorBootstrap : InstallerFactory
{
public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
{
var retval = installerTypes.OrderBy(x => this.GetPriority(x));
return retval;
}
private int GetPriority(Type type)
{
var attribute = type.GetCustomAttributes(typeof(InstallerPriorityAttribute), false).FirstOrDefault() as InstallerPriorityAttribute;
return attribute != null ? attribute.Priority : InstallerPriorityAttribute.DefaultPriority;
}
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class InstallerPriorityAttribute : Attribute
{
public const int DefaultPriority = 100;
public int Priority { get; private set; }
public InstallerPriorityAttribute(int priority)
{
this.Priority = priority;
}
}
When starting application, global.asax etc:
container.Install(FromAssembly.This(new WindsorBootstrap()));
You can call your installers in the order they need to be instantiated in Global.asax.cs or e.g. in a Bootstrapper class, which is called from Global.asax.cs.
IWindsorContainer container = new WindsorContainer()
.Install(
new LoggerInstaller() // No dependencies
, new PersistenceInstaller() // --""--
, new RepositoriesInstaller() // Depends on Persistence
, new ServicesInstaller() // Depends on Repositories
, new ControllersInstaller() // Depends on Services
);
They are instantiated in this order, and you can add a breakpoint after and check the container for "Potentially misconfigured components".
If there are any, check their Status->details, if not, it's the correct order.
This solution is quick and easy, the documentation mentions using a InstallerFactory Class for tighter control over your installers so if you have a ton of installers the other solution may fit better. (Using code as convention should not require tons of installers?)
http://docs.castleproject.org/Windsor.Installers.ashx#codeInstallerFactorycode_class_4
In the end i had to use InstallerFactory and implement the ordering rules as suggested previously by returning the IEnumerable<Type> with my specific order

Resources