Saving preferences from two classes in Libgdx - libgdx

I have a problem with Preferences that I wonder if someone can help me with?
I am working on a game with a settings screen and a game screen. Both needs to be able to write to the same Preferences. The code works in the Settingsscreen, it looks like this:
public class SettingsScreen implements Screen{
private Preferences prefs;
final Preferences prefs = Gdx.app.getPreferences("myprefs");
prefs.putFloat("volume", volume);
and in the Gamescreen I get an error. The code in the Gamescreen looks the same as in settings. This works:
volume = prefs.getFloat("volume", 1);
but this does not:
prefs.putFloat("volume", volume);
I get the following error:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.mullenuh.learntoread.Screens.GameScreen$4.clicked(GameScreen.java:259)
at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:89)
at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:58)
at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:353)
at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:332)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)

You probably have a local variable called "prefs" in the constructor and member variable also called "prefs" which is still null since you only assign the Preferences instance to the local scope variable.
private Preferences prefs; // class member variable
final Preferences prefs = Gdx.app.getPreferences("myprefs"); // local scope variable
The reason why this works in your SettingsScreen is probably cause you do the calls on prefs within the local scope.
This is what you probably want:
// class member variable
private final Preferences prefs;
// constructor:
this.prefs = Gdx.app.getPreferences("myprefs");

Related

Using MySQL with visual studio and changing the connection at runtime

I use something like this for my application
MySqlConnection cnn = new MySqlConnection("Server=myServerAddress;" +
"Database=myDataBase;" +
"Uid=myUsername;" +
"Pwd=myPassword;");
And this changes everytime because we deploy databases with our application.
It works fine. I type in using(new connection(cnn)){ query... } and go.
And I've got it working with a dataset using a connection defined in the windows ODBC datasouce administrator.
But I'm curious, is there a way to use visual studio's dataset items using the my local test db and then change the connection of the dataset at runtime? Even better, can I use c# to programmatically add the ODBC data source at runtime?
Usually a connection string is loaded from the application exe.config file present in the same folder of the application. This connection string could be defined using the Settings tab in the project properties.
Right click on Properties of your project
Select the Settings tab (confirm the creation if you have no
settings)
Click on the ComboBox in the column type and select Connection String
Give a symbolic name to your connection
Type the connection string in the Value column (Examples at
connectionstrings.com)
Now in your project files you should have the file app.config (that becomes yourapp.exe.config) where there is a section like this
<configuration>
<connectionStrings>
<add name="MyAppConnection"
connectionString="Server=myServerAddress;Database=myDB;Uid=user;Pwd=pass;" />
</connectionStrings>
</configuration
At this point you read it in the program using
string conString = ConfigurationManager
.ConnectionStrings["MyAppConnection"]
.ConnectionString;
Instead in a dynamic situation where you want to build yourself the connection string during runtime (from user inputs, your own configuration files and so on) then you could leverage the functionality of the class MySqlConnectionStringBuilder
MySqlConnectionStringBuilder msb = new MySqlConnectionStringBuilder();
msb.Server = "localhost";
msb.Port = 3306;
msb.UserID = "root";
msb.Password = "xxx";
msb.Database = "test";
MySqlConnection cnn = new MySqlConnection(msb.ConnectionString);
cnn.Open();
Of course, these literal values could be substituted by your own variables.
The documentation of this class is surprising difficult to find. The best docs are the one of the Sql Server equivalent. It is interesting that you could read a static connection string from your config file and then change only the property needed.
string conString = ConfigurationManager
.ConnectionStrings["MyAppConnection"]
.ConnectionString;
MySqlConnectionStringBuilder msb = new MySqlConnectionStringBuilder(conString);
msb.Database = "AnotherDB";
MySqlConnection cnn = new MySqlConnection(msb.ConnectionString);
Application connection string cannot be changed at runtime.
User settings can be changed.
Assuming you are using an application setting-property named "MyConnectionString" which holds the connection string for the entire application.
On your main Program class create a global string:
internal static string Prconnstring;
Create and save this settings.cs file:
namespace MYSOLUTIONORPROJECTNAME.Properties
{
// (Not sure where I found this solution some time ago)
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
internal sealed partial class Settings
{
public Settings()
{
// // To add event handlers for saving and changing settings, uncomment the lines below:
//
// this.SettingChanging += this.SettingChangingEventHandler;
//
// this.SettingsSaving += this.SettingsSavingEventHandler;
//
}
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e)
{
// Add code to handle the SettingChangingEvent event here.
}
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e)
{
// Add code to handle the SettingsSaving event here.
}
public override object this[string propertyName]
{
get
{
if (propertyName == "MyConnectionString")
{
return Program.Prconnstring;
}
else
{
return base[propertyName];
}
}
set
{
base[propertyName] = value;
}
}
}
}
Before calling-opening any object that uses the connection string (examples include Forms that use datasets or other classes that use datasets created on the development enviroment) create your new connection string by any means you think. (Example: You might want to use as user name in the connection string the current user. Create the connection string using the info provided form the environment.)
Program.Prconnstring = thenewruntimeconnectionstring.
Now whenever the application tries to get MyConnectionString (which is hardcoded in the myapplicationname.config and cannot be changed) instead gets the new thenewruntimeconnectionstring you provided to Program.Prconnstring.
Be aware that the development connection string will be available-visible to final user, since it is just a text file. If you do not want this, you can change that file (will be a file named NAMEOFMYAPPLICATION.exe.config) during deployment, since the connection string hardcoded there, will be of no use for the running app. Do not delete it, just change.
Your connection string will be stored in your App.config (or c# equivalent). Say it's called MyConnectionString. Just add My.Settings("MyConnectionString")="[your new connection string]" to your entry point to change to database binding at runtime. E.g:
Public Sub New()
' This call is required by the designer.
InitializeComponent()
My.Settings("MyConnectionString") = "server=remotedb.uk;user id=MainUser;password=2jdi38edhnche73g;database=mainDb;persistsecurityinfo=True;allowuservariables=True;defaultcommandtimeout=480;characterset=utf8mb4"
End Sub

Custom Neo4j GraphViz Writer

I have an application which produces a GraphViz dot file for a subgraph of my Neo4j database. It works like a charm, but there is somewhat of an issue.
Right now, the title of each node is the node id. Then the properties are listed, with their respective types. This is more information than I need and I would like to change the way the GraphViz writer is configured.
I noticed several classes/interfaces such as GraphStyle, StyleParameter, StyleConfiguration but I've tried several things and keep running into the issue that I cannot access certain classes/interfaces outside of their respective package. Maybe I'm doing it wrong, maybe it's designed so users cannot reconfigure the GraphViz writer, I don't know but I'd like to know.
How do I reconfigure the GraphViz writer so the dot file contains only that information which I want it to contain, namely a property of my choosing as the title, and nothing else as far as the nodes are concerned. Also, this is not always the same property, so for some nodes I'd like property A to be the title, and for nodes that don't have property A, I'd like property B to be the title.
Any help would be greatly appreciated.
You could try using the styles provided by this class: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/graphviz/AsciiDocSimpleStyle.java
It might be useful to look into this class as well: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/asciidoc/AsciidocHelper.java
I managed to get it to work. First of all, you need to create two new classes:
class NodeStyleImpl implements NodeStyle
class RelationshipStyleImpl implements RelationshipStyle
Here you can define how nodes and relations should be written in the dot notation. An example implementation looks like this :
public class NodeStyleImpl implements NodeStyle {
public void emitNodeStart(Appendable apndbl, Node node) throws IOException {
apndbl.append(" N" + node.getId() + " [\n label = \"");
}
public void emitEnd(Appendable apndbl) throws IOException {
apndbl.append("\"\n]\n");
}
public void emitProperty(Appendable apndbl, String propkey, Object propvalue) throws IOException {
if(propkey.equals("propkeyone") || propkey.equals("propkeytwo"){
apndbl.append(propvalue.toString());
}
}
}
In an analog fashion, you can write the RelationshipStyleImpl. If you're looking for more advanced configuration, you can also write a StyleConfiguration implementation. You can look at the default implementations in the Neo4j code for an example.
Then there's the issue with the GraphStyle class. The GraphStyle class has a constructor which is protected, thus only accessible from within the package. I made a pull request to change it to public but for the moment, here's a little "hack" which provides a workaround.
package org.neo4j.visualization.graphviz
public class GraphStyleImpl extends GraphStyle {
private GraphStyleImpl (NodeStyleImpl nstyle, RelationshipStyleImpl rstyle) {
super(nstyle, rstyle);
}
}
Note the package declaration. Because the GraphStyle constructor is protected, the super(nstyle, rstyle) method is only accessible from within the same package. By extending the class with a new public constructor, you can now do the following:
GraphStyle graphstyle = new GraphStyleImpl(new NodeStyleImpl(), new RelationshipStyleImpl());
GraphvizWriter writer = new GraphvizWriter(graphstyle);
If my pull request gets accepted, the use of the GraphStyleImpl class will no longer be necessary.

JRuby field_accessor final member

I have a java field that I want to subclass in jruby defined like so:
public abstract class FilterObjectStream<S, T> implements ObjectStream<T> {
protected final ObjectStream<S> samples;
I then want to subclass this class and access this member, I have tried to access the protected final member like this, using field_accessor:
class NameSampleDataStream
field_accessor :samples
end
class HtmlNameSampleDataStream < NameSampleDataStream
def read
token = self.samples.read()
token
end
end
I am getting an error message:
SecurityError: Cannot change final
field 'samples'
I guess the exception answers the question but is there anyway that I can access this variable or is the game up?
I cannot change the java source unfortunately.
Can you try just doing "field_reader"? It's possible to set a final field accessible, but we don't do that for you, and what you want here is just a reader, right?

Castle Windsor resolve named instance and unnamed instance incorrect

I have following testing code trying to get one instance for generic and other for special purpose.
[TestMethod]
public void Test_Name_And_Named_Instances()
{
//MyClass implemented IMyClass
MyClass genericInstance = new MyClass("generic");
MyClass specialInstance = new MyClass("special");
IWindsorContainer container = new WindsorContainer();
container.Register(Component.For(IMyClass).Instance(genericInstance));
container.Register(Component.For(IMyClass).Instance(specialInstance).Named("special"));
IMyClass genericOne = container.Resolve<IMyClass>();
IMyClass specialOne = container.Resolve<IMyClass>("special");
Assert.AreSame(genericOne, genericInstance); //true
Assert.AreNotSame(genericOne, specialOne); //false
}
I expect to get two different instances, but the result is both genericOne and specialOne points to same objec genericInstance.
Any idea?
This doesn't compile:
container.Register(Component.For(IMyClass).Instance(genericInstance));
Should be:
container.Register(Component.For<IMyClass>().Instance(genericInstance));
Other than that, the test passes for me (Windsor 2.5.2)
EDIT:
If you flip the registrations, the test fails. This is by design. When you resolve without an explicit name, you're saying "give me the default component for this service", which in Windsor is the first registered component for that service type, by default.
If you need different components under the same service type, assign explicit names to all of them when registering and resolving.

Reading System Variable from Script Component

What is the best way to read system variables from Script Component.
Tried as below: Works fine when is User variable
base.PreExecute();
IDTSVariables100 variables = null;
VariableDispenser.LockForRead("System::ContainerStartTime");
VariableDispenser.GetVariables(out variables);
auditTimeStamp = Convert.ToDateTime(variables[1].Value);
System.Windows.Forms.MessageBox.Show(auditTimeStamp.ToString());
variables.Unlock();
when tried to read System variable throws following error:
Script Component has encountered an exception in user code:
Project name: SC_0bfc7da1c6fe4b83bc124b87eb4178e5
Exception from HRESULT: 0xC0010009
at Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSVariables100.get_Item(Object Index)
at ScriptMain.PreExecute()
at Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost.PreExecute()
any clues please.
Thanks
You have changed the index, from
Convert.ToDateTime(variables[1].Value);
to
Convert.ToDateTime(variables[0].Value);
Ok got this done as
#region Class Variables
int jobId;
DateTime auditTimeStamp;
IDTSVariables100 variables;
const string tableName = "ORGANISATION_PROVIDER";
#endregion
public override void PreExecute()
{
#region On PreExecute - Get the JOB ID passed - COMMON
base.PreExecute();
variables= null;
VariableDispenser.LockForWrite("System::ContainerStartTime");
VariableDispenser.GetVariables(out variables);
auditTimeStamp = Convert.ToDateTime(variables[0].Value);
variables.Unlock();
#endregion
}
This works fine..not sure what i have done wrong previously.
You could create a user variable that is evaluated as an expression that references the system variable. Something like this
#[System :: PackageName].