So I have got this class called TypingKeyboard. It's a class that draws a string on the screen as if it is typed by someone, with sounds. I use this for many things, for example in the main menu, credits and the game itself.
class TypingKeyboard
{
SoundEffect foo;
public TypingKeyboard(string text, int intervalBetweenKeys, blah blah blah){}
public void LoadContent(ContentManager content)
{
foo = Content.Load<SoundEffect>("keysoundthinggy");
}
}
In order to hear sounds you need to load the sounds, and store them. This happens for every instance of the class I have.
So every time you make this class, you need to call LoadContent and it loads the SoundEffect to the RAM. This is not very efficient since I always use the same sounds.
Is there a way that I can create a class that you need to make an instance of once and then can call the sounds from "anywhere" I want?
Like this:
// I need to play the sound!
TypingKeyboardData.Foo.Play();
Use the lazy singleton pattern:
public class TypingKeyboardData
{
private static readonly Lazy<TypingKeyboardData> _instance
= new Lazy<TypingKeyboardData>(() => new TypingKeyboardData());
// private to prevent direct instantiation.
private TypingKeyboardData()
{
}
// accessor for instance
public static TypingKeyboardData Instance
{
get
{
return _instance.Value;
}
}
// Add all required instance methods below
}
More here.
Related
What I am currently atempting to make is an inventory system. I wonder if I can store the current method and then open the inventory, and when I am done there, reopen/recall the previus method that ran.
You haven't provided very much information but I can tell you don't want to store a method, you want to store an object.
An object is an instance of a class. Depending on the kind of class you have you can either create multiple instances of a class and instantiate them multiple times across your application. Or alternatively you can create single instances of an object that you use throughout your entire application/game.
From the sounds of it, you want to use a singleton class that retains the current values of the user's inventory. So if you interact with the inventory class in one part of your program, you would like to then view and interact with the same previously modified values stored within the singleton from another part of your program.
I can't give you a concrete answer to your problem, but a possible Singleton class for your use case would look something like this;
public sealed class Inventory
{
private static readonly Inventoryinstance = new Inventory();
// Explicit static constructor to tell C# compiler
// not to mark type as before field init
static Inventory()
{
}
private Inventory()
{
// optionally, pre-populate with data stored in database when constructed
}
public static Inventory Instance
{
get
{
return instance;
}
}
public List<InventoryItem> InventoryItems { get; set; } = new List<InventoryItem>();
public void AddItemToInventory(InventoryItem item) {
InventoryItems.Add(item);
}
public void RemoveItemFromInventory(InventoryItem item) {
InventoryItems.Remove(item);
}
}
You can use this site for reference - https://csharpindepth.com/articles/singleton
If you have an application that utilises DI, you can create singleton instances that are injectable into your other app classes. This is a better way of handling singletons as they are handled by an IoC system rather than being made static for the entire application to access.
I don't think I explained my question very well in the title, so I'll do my best to do it here.
I have an abstract class called Song, a class that extends it MidiSongand then I have a SongCreator interface and a MidiSongCreatorclass that implements it. I would like to have a way to store lots of SongCreators so I can call their Create method but the problem is, since the SongCreators will each be a MidiSongCreator I am wondering how I should initialize each MidiSongCreator since it takes a MIDIPlayer and other things to help initialize it which doesn't have a static reference to it. Should I create a static class that holds lots of SongCreators? Should I not make the SongList class static?
What is looks like:
public abstract class Song{
public IList<Playable> notes { get; private set; }
public SongPlayData Start(){
// calls onStartEvent
return CreateSongData();
}
protected abstract SongPlayData CreateSongData();
public bool Update(SongPlayData songData, float songTime,List<SongPlayer> players) { // note that the players list is a list of people who are playing this game (this is a rhythm game) (doesn't have anything to do with MIDIPlayer
}
public void End(){
//calls end event
}
}
public class MidiSong : Song { // this is the class that needs the MIDIPlayer parameter
public MIDIPlayer midiPlayer;
protected MidiSong(MIDIPlayer player){
this.midiPlayer = player;
}
protected override SongPlayData CreateSongData() {
return new MidiSongData(midiPlayer);
}
}
public interface SongCreator<out T> where T : Song {
T Create();
}
public class MidiSongCreator : SongCreator<MidiSong>, IListenerObject { // this is the class that I need to store lots of instances of. the midiPlayer will probably be the same every time
private MIDIPlayer player;
public MidiSongCreator(MIDIPlayer player) {
this.player = player;
Init();
}
private void Init() {
player.midiListener.listener = this;
//
}
private void Clear() { // resets all the data so we can create another Song if we need to (even without entering stuff in)
if(player.midiListener.listener == this) {
player.midiListener.listener = null;
}
}
public MidiSong Create() {
MidiSong r = new MidiSong(player);
// I'm still going to implement calls to other methods from midiPlayer
Clear();
return r;
}
public void OnLoad(MidiFile file) {
// does stuff to load midi file (deals with individual events)
}
}
public class MasterSong : MonoBehaviour { // this should initialize last btw (It's in the Script Execution Order)
public MIDIPlayer midiPlayer;
public Song song;
public SongPlayData playData;
// Use this for initialization
void Start() {
// this is where I'd like to reference a SongCreator and call it's create method and Start the song
//for instance:
song = SongList.SONG_NAME.Create();
playData = song.Start();
}
void Update() {
}
}
It's a RhythmGame made with unity, but I didn't add the unity tag because I feel that this is more of a C#/design thing.
Also note, that I have my classes much more organized that just one file with all these.
I'm looking for ways to improve on the design that I have.
This is a design problem, domain design!
I suggest don't write code yet. Create a class diagram, with pen and paper, don't need to use tools in the beginning.
Try to determine entities - classes, interfaces etc - and the relationship among them. Just use boxes and arrow, don't need to put details yet. With boxes and arrows, you will be able to have a picture of your domain much more clearly. Keep refining and changing it, still at this high level, without details, until you are satisfied.
Then, step by step, refine it by adding details/properties such attributes and methods. This may cause to change the diagram from the first step.
I intentionally did not refer to specifics of you questions like the classes and interfaces you mentioned. Since, there is not enough information to comment on that. Secondly, and more importantly, you should start at high level of design and once that is done, then do coding based on your design.
So, apologies in advance for the surely poor terminology in this question - I'm trying to teach myself C#, and struggling with a few concepts.
In pseudo-code, I have something like this:
static void Main()
{
// This will create lots of "Item"(s), and do stuff with them
}
public class Item
{
// a bunch of properties
public Item()
{
}
}
Next, I need a UtilityFunction1 that'll do some work - it will be called many times during Main() and passed Items to do some calculations with them. This function needs to set up a Dictionary to do its job. Even though it will be called many times, the Dictionary should only be set up once.
I also need a UtilityFunction2. Like UtilityFunction1, this function also needs a Dictionary to do it's job, which should only be set up once. This function will be called many times by UtilityFunction1.
So, on one hand, it seems like UtilityFunction1 and UtilityFunction2 should be public classes, since they need to have a constructor that populates the Dictionary (which involves variables, looping, and calculations).
On the other hand, I only need one of UtilityFunction1 and UtilityFunction2, so it seems like they should be static methods. But if that's the case, how/when do they do the work to set up the Dictionaries they need?
How do you achieve this?
You could also move your logic outside of Main.
What forces you to use static is that Main method (and class it's part of, usually) is static. That forces all other things (fields, methods, events, you name it) to also be static. The easiest way of curing that headache would be to create new class to hold all things you need.
Create new Logic class and put all things in it. The Item class stays the same. you can move it to separate file for clarity.
Logic.cs:
public class Logic() {
private Dictionary<object,object> dict1 = new Dictionary<object,object>
private Dictionary<object,object> dict2 = new Dictionary<object,object>
public Logic() {
// some logical initializations here
}
private void UtilityFunction1 (Item itemToWorkOn) {
// you can access dict1 directly from here
}
private void UtilityFunction2 (Item itemToWorkOn) {
// you can access dict2 directly from here
}
public void Run() {
// run UtilityFunction1() many times
// run UtilityFunction2() many times
}
}
Item.cs:
public class Item() {
// a bunch of properties
public Item() {}
}
And then just run it in your Main.
Program.cs:
static class Program {
static void Main() {
new Logic.Run();
}
}
Maybe you can think of the Singelton Design Pattern for your UtilityFunction*
https://msdn.microsoft.com/en-us/library/ff650316.aspx
You need a class that has only one instance, and you need to provide a global point of access to the instance.
You may use a static constructor. A static constructor is guaranteed to be executed just once for the class and before the class is used for the very first time. A static constructor is a very good place for initialization of static properties. It may look like:
public class ExampleClass
{
public static readonly IDictionary<int, Item> Items;
static ExampleClass()
{
Items = new Dictionary<int, Item>();
}
}
However, be careful with static stuff as it usually decreases the modularity and testability of a program. Therefore the use of a singleton pattern might be a better solution rather than a static constructor.
I'm trying to learn MonoGame and I'm trying to do basic stuff and I've figured most of it out on my own but I'm getting a null pointer and I'm not sure why. I'm trying to get MainMenuScene to just draw a texture but in SceneManager currentScene keeps giving me null pointers and I have no idea why. Ill post my SceneManager code but the rest will be on github. Its not much code so it shouldnt take long if you'd look over it. I'm super confused and I'm not sure what to google to try to figure it out myself.
https://github.com/eatmykhack/MonoGame.git
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tutorial.Scenes;
class SceneManager
{
private static SceneManager instance = new SceneManager();
Scene currentScene, newScene;
Dictionary<string, Scene> sceneDirectory =new Dictionary<string, Scene>();
public static SceneManager getInstance()
{
return instance;
}
public static Scene getCurrentScene()
{
return instance.currentScene;
}
public static void changeScene(Scene scene)
{
}
public static void addScene(string sceneName)
{
instance.newScene = instance.sceneDirectory[sceneName];
}
public void update() { currentScene.Update(); }
public void draw(SpriteBatch spriteBatch) { currentScene.Draw(spriteBatch); }
public void Initialize()
{
instance.sceneDirectory["MainMenuScene"] = new MainMenuScene();
instance.currentScene = instance.sceneDirectory["MainMenuScene"];
}
public void LoadContent(ContentManager content)
{
instance.currentScene.LoadContent(content);
}
public void UnloadContent()
{
instance.currentScene.UnloadContent();
}
}
you've declared Scene as an abstract class, so you can't just use it as you're doing: Scene currentScene, newScene. (See this reference for more details on abstract classes).
Either make scene a non-abstract class type or create another class that inherits from your abstract class, looking at your code it would be something like:
public class myScene : Scene
{
public override void Update()
{
//do something
}
// etc.
}
You are getting a NullReferenceException because you are mixing static and instance fields in your code:
There are several problems:
Your SceneManager has a public constructor, but its instance method all access the same static (singleton) instance.
Your SceneManager.Draw method does not access the static instance.
Your Game class instantiates a separate ScreenManager instance, meaning the singleton is initialized, but the Games instance isn't. This is allowed because of 1.
There are several ways of fixing this:
The Preferred way: remove the static stuff from SceneManager. Your game is going to have a single instance in the Game class anyway, and you can simply pass the instance along to any scenes. A no brainer.
However, if you want to keep this class a singleton, you need to change a couple of things. People usually want this because they are too lazy to pass the SceneManager along to each scene instance. So, singletons are bad, you won't be able to unit test anything, but I believe most indie game developers don't care too much about unit testing and would be happiest if everything was static and accessible from anywhere.
Make the constructor private, so that no other class (like Game) can instantiate it. If anyone wants to access the instance, they should do it through the getInstance() method. Which, btw, might better be a property instead:
public class SceneManager
{
// private constructor means other classes cannot instantiate this
private SceneManager() { }
private static readonly SceneManager _instance = new SceneManager();
public static SceneManager Instance
{
get { return _instance; }
}
}
If you now try to pull this off in your Game class:
var sceneManager = new SceneManager();
your compiler will tell you it's not going to work that way.
Your SceneManager should only have a single static method/property: getInstance() or the Instance property like shown above. All other methods should be instance methods of that one-and-only instance, and not access the instance field at all. They are accessing that instance anyway. It is a bad idea to have instance methods access static fields:
This is wrong:
public void Initialize()
{
var mainScene = = new MainMenuScene();
instance.sceneDirectory["MainMenuScene"] = mainScene;
instance.currentScene = mainScene;
}
But this is fine (and the this keyword is redundant, of course):
public void Initialize()
{
var mainScene = = new MainMenuScene();
this.sceneDirectory["MainMenuScene"] = mainScene;
this.currentScene = mainScene;
}
Because you're going to use it like this anyway:
// you're basically doing the same thing, but
// it's immediately clear what's going on, and there
// is no room for errors:
var manager = SceneManager.Instance;
manager.Initialize();
The simplest way to ensure you're doing it right it to remove all references to instance inside the SceneManager class.
I don't want to create an object because it won't affect my visible form. How can I call a method so it does its thing in the visible side of things.
public class foo
{
public void SetString(string foo)
{
label1.Text = foo;
}
}
Inside another class:
foo X = new foo();
X.SetString("testlololol");
This will set the label, but VIRTUALLY, I won't be able to see it on my form.
How can I do the same thing, but on my VISIBLE side of things?
When you create your visible form store a references to it in some static property. Then other classes can use that property to run public methods of that class.
// the original form
class MyForm()
{
// form public method
public void MyMethod() { ... }
}
// class storing the reference to a form
class MyOtherClass
{
public static Form MyForm;
public void ShowForm()
{
MyForm = new MyForm();
MyForm.Show();
}
}
// invoke form public method in this class
class YetAnotherClass
{
public void SomeMethod ()
{
MyOtherClass.MyForm.MyMethod();
}
}
You need to somehow get the instance which is visible. Work out some information path from things that already know about your form (or whatever it is) to your other code. Consider what would happen if there were two visible forms - which one would you want? That should suggest a way forward. If you know for a fact that there'll only ever be one visible instance, you could use a singleton - but I'd strongly suggest that you don't.
Bear in mind that you may not need to know of it by its full type name - if this is crossing layers, you may want to work out some interface including the action in some abstract way.
I would usually either pass a reference of my form ('foo' in this case) to the other class. Or I would store off a copy of 'foo' to some static location. If you know that there will only ever be 1 instance of 'foo' you could do something like:
public class foo
{
public static foo Current { get; private set; }
public foo()
{
foo.Current = this;
}
public void SetString(string foo)
{
label1.Text = foo;
}
}
...and...
foo.Current.SetString("testlololol");
Though thats a bit hacky IMO, and doesnt support multiple instances of 'foo'.
Your second class needs to have a reference to the instance of the class that IS visible.
public class OtherClass{
foo myFoo;
public OtherClass( foo visibleFoo )
{
myFoo = visibleFoo;
}
public void method()
{
myFoo.SetString("testlolol");
}
}