i have this problem, i want to create a small game, for an university project using c#, i need to create a small dll library that contains the game logic, but the core of logic is handle the keyboard events. I know that "System.Form.." allow to listen for keyboard events, but is there a method to handle single keyboard events without using the Form library? I need to create a event that is "launched" when a keyboard button is pressed, an event "like" this:
public OnKeyPress(KeyCode c)
There is a method?
Thanks in advance.
You need something that loads and uses a DLL. The DLL by itself is not going to run. We need some more information regarding how this library will be used. You can create a library that has only processing classes/functions, but somewhere the keyboard will have to be monitored.
Here is a post that discusses global keyboard monitoring. The answer of that question links out to an MSDN article.
Back to what I initially mentioned, you do not need to have the actual events in your library. You can create a library containing only functional code. That code could then be called from a higher level in the overall application where the events are handled. Here is a very simplistic, and honestly hackish, example:
public static class MyKeyboardActions
{
public void HandleKeyCharPress(char keyPressed)
{
switch(keyPressed)
{
case 'A':
// do code for key: A
break;
case 'B':
// do code for key: B
break;
// etc...
}
}
}
If you want something more specific than this, you would need to elaborate more about your project in your question, then I can expand my answer more if needed. As you can see though, there is no need for a System.Windows.Forms reference with that code.
Related
I am creating a program which shows a form with a text field and activate button, there are certain code which are entered by the user in the text field and on clicking activate button it does the work based on the code inputted by user.
I have successfully created a form and in the activate button click event it calls the method of another class (named Output) like below
Output o = new Output();//Created object for output class
o.effect(s.Text);//here effect() is function of Output and s is textfield
And in Output class's effect() function
void effect(String str)
{
switch(str)
{
case "code1": Console.Write("you enter code1"); //all the things to be done if code1 input
break;
...
...
default: ...;
break;
}
}
The above classes were successfully compiled and run properly. But now I want to make a dll support for this program so that whenever I have to add more code I can just easily create a new dll (Say, Outputversion2.dll) in which there are code like above Output class which can be entered in main program form.
Something like a code extension...
I don't want to mistakenly damage the main program by editing every time to add more codes that's why I thought of it.
Hope you understand what I want to do.
I am just beginner with c# , just learned a month ago.
Sorry for any Grammar error, my English is also not so good.
Thank U.
I'm not sure what you are trying to do here. If you're hoping to be able to dynamically add new DLLs, each with a set of handlers (i.e. cases), then you should probably use the Managed Extensibility Framework. Otherwise, if what you are trying to do is to simply have all handlers in one separate DLL that can be replaced at any time, you should place the Output class in a Class Library, which will compile into a DLL; you can then swap out versions of this DLL without worrying about changing the main program, so long as you don't change the interface (the classes and their functions' return types and parameters; you can change the code inside the function as much as you want).
Also, if your worried about destabilizing the main program, I would recommend keeping backups of the source code, and not releasing new versions until you have fully tested them multiple times.
I hope this helps.
I have a .Net 4 control /.dll which I am using with LabVIEW.
The control exposes the following event:
public delegate void CommNewDataEventHandler(UInt16 u16StageGroup, UInt32 u32Status , string [] strNewDataTitle, float[] fNewData, string[] strNewDataUnit);
public event CommNewDataEventHandler CommNewDataEvent;
What I would like to do is subscribe to this event within LabView and update a numeric indicator with the value specified in float[] fNewData.
What is the correct way to do this?
current VI callback VI
There is no "correct" way to do this, but you can put code in the callback VI to pass data to where you need it.
For example, you can pass the control reference as the user parameter (this is the terminal on the register node and the control on the FP) and then use Variant to Data to convert it back to a reference (edit - you don't need to convert if you create the VI after wiring the data into the node) and use the value property. This is inelegant, but it will work.
A more elegant solution would be to pass a user event of your data type to the callback VI (for instance, as the user parameter) and then generate that event with the data you got. This is more cumbersome, but less hidden.
Like so (ignore the missing horizontal wire. It must have blinked when I took the screenshot, but it's there):
You can find the image here if imgur takes it down: https://forums.ni.com/ni/attachments/ni/130/16266/1/event%20callback%20example.PNG
As the previous poster has suggested, there is no "correct" way to do this. There are a number of different approaches you might take depending on the scope of your project. For the general .NET event registration and handling procedure NI has a good example here: https://decibel.ni.com/content/docs/DOC-9161
This sample code is a "timer handler" (using a native .NET timer API) and illustrates how to register for an event and create your callback VI. Let's modify this to achieve your goal. To do so, we must somehow communicate through our callback VI to another part of the program (containing the numeric indicator we want to update). Options for establishing communication between seperate parts of our application:
Global variables
Functional global variable
Control/indicator references
Structured synchronization mechanism (i.e. queue, notifier, etc.)
Messaging system (i.e. UDP via local loopback, managed queues, etc.)
There are many, many options and this is certainly not an exhaustive list. Every approach has advantages and disadvantages and your decisions should be based on what kind of application you are writing. Note that some are better style than others. My preference (when writing fairly simple application) would be to use something like a notifier for a single point data update. My opinion is that this offers a good amount of flexibility/power and you won't get knocked for style points.
Below is a modified version of NI's example program using a notifier to pass the data from the callback VI to the top level VI. When the event fires, the callback pushes some data onto the notifier to signal to the top level VI that the elapsed time has expired and the event has occured. The top level VI waits for the notification and uses the provided data to update the value of the numeric indicator.
Note that this is a very trivial example. In this case I don't really even have to send any data back. I know that if the notifier does not timeout that the event has fired and can subsequently increment my counter in the top level. However, the notifier allows you the flexibility to stuff arbitrary data in the communication pipe. Hence, it can tell me "hey! your condition occurred!" and "here's some data that was generated".
Callback VI
Top Level VI
If you are writing a larger application, your loop to monitor the notifier can run in parallel with other code. Doing so allows you have an asynchronous mechanism for monitoring the status of the event and displaying it on the GUI. This approach allows you to monitor the event without interfering with the rest of your application.
Most of the functions in my WinForms application have a key press alternative. There are a lot of them. At the moment I am handling this in a switch statement. My code analyzers tell me that this code is un-maintainable to varying degrees of nasty. I have to agree. I would extract the handling code out to separate methods but in most cases this is only a line or two and it does not really help me get a handle on things.....
Is there are better way to handle this of am I stuck with a huge switch?
Thanks in advance
Somewhere in the code, soon or later, you will need to make swicth/case or if/else, or whatever. So pushing actual handling code for every Key or Key combination to separate function is already good step.
You may be can other "nice" stuff: make a dictionary where
Key: is keyboard key
Value: delegate to call on that key press
And basically what you will need to do is to say, pseudocode!!
dictionary[key].Invoke();
Hope this will give some hints.
Regards.
You could use a Dictionary to map different key presses to functions, and add to that Dictionary wherever it made sense structurally. For a very simple example:
public partial class Form1 : Form
{
Dictionary<Keys, Action<object, KeyEventArgs>> KeyPressLookup;
public Form1()
{
KeyPressLookup = new Dictionary<Keys, Action<object, KeyEventArgs>>();
KeyPressLookup[Keys.F10] = (o, e) => MessageBox.Show("You pressed F10");
InitializeComponent();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(KeyPressLookup.ContainsKey(e.KeyCode) // Could use TryGetValue instead
KeyPressLookup[e.KeyCode](sender, e);
}
}
This code has the limitation that only one function can be assigned to a key, which may be good or bad. Of course you could make a Dictionary of Lists or "MultiDictionary" if you want multiple functions per key.
Alternatively, you could have multiple Dictionaries, and have them be used depending on the circumstances, such as user options or the current "mode" (depending on how your application is structured).
Using lambda functions the resulting code overall can be much more concise than defining a "regular" function for every key.
You might also want to come up with a concise way to define functions mapped to key combinations such as Ctrl-F10. How far you want to go would depend on the size of your application.
Implement a Command system (Like WPF).
If you seperate the logic of all your functions into individual Commands you can then attach these commands to your menu items etc
take a look at http://www.ageektrapped.com/blog/using-the-command-pattern-in-windows-forms-clients/
If you modify that code slightly so that you add the command.Key into the Dictionary examples given in the other answers you get your solution.
Alternatively each Command could contain a delegate method for the Form_keydown event that you attach when you attach the command and you can then analyse the keypress in the command and choose to process if it matches.
I'm currently implementing a script engine in a game I wrote using the C# "dynamic" feature.
How the system should work is when a script is called, it should register the events it listens for, then return control to the application. Then when an event that the script is listening for is fired the script should execute. One thing I'd really like to implement in the script engine is to have methods with certain names automatically bind to events. For example, the onTurnStart() listener should automatically bind to the turnStart event.
The scripts will mostly need to execute existing methods and change variable values in classes; stuff like player.takeDamage() and player.HP = somevalue. Most scripts will need to wait for the start of the players' turn and the end of the players' turn before being unloaded.
The complicated part is that these scripts need to be able to be changed without making any code changes to the game. (Security aside) the current plan is to have all the script changes automatically download when the game starts up to ensure all the players are using the same version of the scripts.
However I have three questions:
1) How do I register and unregister the script event listeners?
2) Can dynamic code listen for events?
3) (How) can I register events dynamically?
This is my first time using C#'s dynamic feature, so any help will be appreciated.
Thanks
--Michael
I'm not sure you've got the right end of the stick with the dynamic keyword. It doesn't by itself let you interpret new code at runtime. All it does it let you bypass static type checking by delaying the resolution of operations until runtime.
If you're looking to "script" your game, you probably want to take a look at integrating Lua, IronPython, or one of the other DLR languages:-
C#/.NET scripting library
IronRuby and Handling XAML UI Events
Otherwise, the usual thing to do is have something along the lines of:-
interface IBehavior
{
// Binds whatever events this behaviour needs, and optionally adds
// itself to a collection of behaviours on the entity.
void Register(Entity entity);
}
// Just an example
public abstract class TurnEndingDoSomethingBehavior
{
public void Register(Entity entity)
{
entity.TurnEnding += (s, e) => DoSomething();
}
private abstract void DoSomething();
}
The question is, do you want to be able to add entirely new behaviours after compile-time? If so you'll need to expose some or all of your game-state to a scripting language.
Or is it sufficient to be able to compose existing behaviours at runtime?
After your edit
I'm still unsure, to be honest, about your requirement for the dynamic keyword and the DLR. Your game's launcher can download a class library full of behaviours just as easily as it can pull down a set of scripts! (That's what Minecraft's launcher does if memory serves)
If you absolutely must use the DLR then take a look at the links I posted. You'll have to expose as much of your game state as necessary to one of the DLR languages. Events get exposed as first-order-function properties. You shouldn't even need the "dynamic" keyword for basic stuff.
Quick example in IronPython:-
def DoSomethingWhenDamageTaken(*args):
#do whatever...
player.DamageTaken += DoSomethingWhenDamageTaken
The player class:-
public class Player
{
public event EventHandler DamageTaken;
// ...
}
You set it up like:-
ScriptEngine engine = Python.CreateEngine();
ScriptRuntime runtime = engine.Runtime;
ScriptScope scope = runtime.CreateScope();
// In an actual application you might even be
// parsing the script from user input.
ScriptSource source = engine.CreateScriptSourceFromFile(...);
Player p = new Player();
scope.SetVariable("player", p);
source.Execute(scope);
Some links to get you started:-
IronPython: http://ironpython.net/
IronRuby: http://www.ironruby.net/
Lua: http://www.lua.inf.puc-rio.br/post/9
For example in Lua you can place the following line at the end of a script:
return <some-value/object>
The value/object that is returned can then be retrieved by the hosting application.
I use this pattern so that scripts can represent factories for event handlers. The script-based event handlers are then used to extend the application. For example the hosting application runs a script called 'SomeEventHandler.lua' which defines and returns an object that is an event handler for 'SomeEvent' in your application.
Can this be done in Python? Or is there a better way to achieve this?
More specifically I am embedding IronPython in my C# application and am looking for a way to instance these script-based event handlers which will allow the application to be extended using Python.
It's totally possible and a common technique when embedding Python. This article shows the basics, as does this page. The core function is PyObject_CallObject() which calls code written in Python, from C.
This can be done in Python just the same way. You can require the plugin to provide a getHandler() function / method that returns the event handler:
class myPlugin(object):
def doIt(self,event,*args):
print "Doing important stuff"
def getHandler(self,document):
print "Initializing plugin"
self._doc = document
return doIt
When the user says "I want to use plugin X now," you know which function to call. If the plugin is not only to be called after a direct command, but also on certain events (like e.g. loading a graphics element), you can also provide the plugin author with possibilities to bind the handler to this very event.
See some examples in Embedding the Dynamic Language Runtime.
A simple example, setting-and-fetching-variables:
SourceCodeKind st = SourceCodeKind.Statements;
string source = "print 'Hello World'";
script = eng.CreateScriptSourceFromString(source, st);
scope = eng.CreateScope();
script.Execute(scope);
// The namespace holds the variables that the code creates in the process of executing it.
int value = 3;
scope.SetVariable("name", value);
script.Execute(scope);
int result = scope.GetVariable<int>("name");
The way I would do it (and the way I've seen it done) is have a function for each event all packed into one module (or across several, doesn't matter), and then call the function through C/C++/C# and use its return value.