I've been trying to create an input field which upon editing activate the scroll View below and display relevant information to the subject(ex:username,address...), but on calling the input field event to activate the scroll view it won't accept the function which I have created. Thank for reading my terrible English and help whoever you're.
public InputField username;
public InputField password;
public List<string> usernamelist;
public Button enter;
public ScrollRect usernamedataload;
// Use this for initialization
void Start () {
string temp = "";
if (PlayerPrefs.GetString ("username") == null) {
username.text = temp;
} else if (PlayerPrefs.GetString ("password") == null) {
password.text = temp;
} else {
username.text = PlayerPrefs.GetString ("username");
password.text = PlayerPrefs.GetString ("password");
}
usernamedataload.gameObject.SetActive (false);
}
// Update is called once per frame
void Update () {
enter.onClick.AddListener (enterKeyDown);
username.onValueChanged.AddListener(selectUsernameInput);
username.onEndEdit.AddListener (endEditingUsernameInput);
}
void selectUsernameInput(){
usernamedataload.gameObject.SetActive (true);
usernamedataload.content.GetChild (usernamelist);
}
void endEditingUsernameInput(){
usernamedataload.gameObject.SetActive (false);
}
It's very hard to understand this question but I can spot big problems already. You are suppose to register to a UI event once. Right now, you are registering to three events every frame in the Update() function. Move those code to the Start() function.
calling the input field event to activate the scroll view it won't
accept the function which I have created
Wrap delegate around the function you are passing in it. For example, username.onValueChanged.AddListener(delegate { selectUsernameInput(); });
Transform.GetChild takes int as parameter but you are passing List to it with usernamedataload.content.GetChild(usernamelist);. I can't tell why you are trying to do that but you should pass an int into it like (1,2,3,4).
You can get started with the code below. It fixes all the problems mentioned above and will compile.
public InputField username;
public InputField password;
public List<string> usernamelist;
public Button enter;
public ScrollRect usernamedataload;
// Use this for initialization
void Start()
{
string temp = "";
if (PlayerPrefs.GetString("username") == null)
{
username.text = temp;
}
else if (PlayerPrefs.GetString("password") == null)
{
password.text = temp;
}
else
{
username.text = PlayerPrefs.GetString("username");
password.text = PlayerPrefs.GetString("password");
}
usernamedataload.gameObject.SetActive(false);
enter.onClick.AddListener(enterKeyDown);
username.onValueChanged.AddListener(delegate { selectUsernameInput(); });
username.onEndEdit.AddListener(delegate { endEditingUsernameInput(); });
}
// Update is called once per frame
void Update()
{
}
void selectUsernameInput()
{
usernamedataload.gameObject.SetActive(true);
usernamedataload.content.GetChild(0);
}
void endEditingUsernameInput()
{
usernamedataload.gameObject.SetActive(false);
}
void enterKeyDown()
{
}
Related
[EDIT] Everything is working now! Thank's to #MrMoonMan!
As the title says, I'm working on a mobile game and I just implemented a Check Update popup.
The thing is, the popup is displayed every time the menu scene is loaded, and this is very annoying because if the player goes to the weapon menu and then comes back to the main menu 10 times, he will see the popup 10 times. The goal is to have the popup appear only once per game session, Here is what I tried for the moment but without success:
Using a bool variable
Destroy the gameobject to which the checkupdate script is attached when the user presses the "No Thank's" button
Here is the code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class CheckUpdate : MonoBehaviour
{
public string versionUrl = "";
public string currentVersion;
private string latestVersion;
public GameObject newVersionAvailable;
private static bool hasBeenChecked = false;
void OnAwake()
{
DontDestroyOnLoad(this);
StartCoroutine(LoadTxtData(versionUrl));
}
private IEnumerator LoadTxtData(string url)
{
UnityWebRequest loaded = new UnityWebRequest(url);
loaded.downloadHandler = new DownloadHandlerBuffer();
yield return loaded.SendWebRequest();
latestVersion = loaded.downloadHandler.text;
CheckVersion();
}
private void CheckVersion()
{
Debug.Log("currentVersion = " + currentVersion);
Debug.Log("latestVersion = " + latestVersion);
Version versionDevice = new Version(currentVersion);
Version versionServer = new Version(latestVersion);
int result = versionDevice.CompareTo(versionServer);
if ((latestVersion != "") && (result < 0))
{
newVersionAvailable.SetActive(true);
}
if (GetChecked())
return;
}
public void ClosePopUp(GameObject obj)
{
obj.SetActive(false);
Destroy(this);
}
public void OpenURL(string url)
{
Application.OpenURL(url);
}
public static bool GetChecked()
{
if (hasBeenChecked)
{
return hasBeenChecked;
}
hasBeenChecked = true;
return false;
}
}
EDIT
Ok so you mentioned that it still happens every time the scene is reloaded. That is because the object is created when the scene is loaded. It isn't saved between scenes. To handle that properly you need to tell it to not get destroyed when the scene is unloaded and to do that is simple, and that is by Adding DontDestroyOnAwake. Here is an example of the code:
public class CheckUpdate : MonoBehaviour
{
public string versionUrl = "";
public string currentVersion;
private string latestVersion;
public GameObject newVersionAvailable;
void OnAwake()
{
DontDestroyOnLoad(this);
}
void OnStart()
{
StartCoroutine(LoadTxtData(versionUrl));
}
private IEnumerator LoadTxtData(string url)
{
UnityWebRequest loaded = new UnityWebRequest(url);
loaded.downloadHandler = new DownloadHandlerBuffer();
yield return loaded.SendWebRequest();
latestVersion = loaded.downloadHandler.text;
}
private void CheckVersion()
{
Debug.Log("currentVersion = " + currentVersion);
Debug.Log("latestVersion = " + latestVersion);
Version versionDevice = new Version(currentVersion);
Version versionServer = new Version(latestVersion);
int result = versionDevice.CompareTo(versionServer);
if ((latestVersion != "") && (result < 0))
{
newVersionAvailable.SetActive(true);
}
}
public void ClosePopUp(GameObject obj)
{
obj.SetActive(false);
}
public void OpenURL(string url)
{
Application.OpenURL(url);
}
}
,,Menu scene''? It sound some suspicious. If you load and unload whole new scene as menu, state as bool field in MonoBehaviours or modifing the scene structure (destory, create object) will not work beacuse allways will be loaded new scene from scratch. ;)
If you have to have menu on seperated scene use someting other to manage the state. For example:
DontDestoryOnLoad objects.
Or some C# static class or singleton (not a MonoBehaviour).
I used the code from Unity and the rewards are multiples... first 1 then 2 then 3 and increasing... i tried deleting some code, but keep doing the same, then this happened.
I searched online and i couldn't find anything that explains clicking the rewarded ads button more than once.
Everything (apparently) is working fine only if i don't assing a button and leave the "SerializeField" empty, because if i remove the button, goes back to give more rewards... can somebody check this and tell me what's going on? i add the code Here
using UnityEngine;
using UnityEngine.Advertisements;
using UnityEngine.UI;
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener, IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] string _androidGameId = "4634758";
[SerializeField] string _iOSGameId = "4634759";
[SerializeField] bool _testMode = false;
private string _gameId;
[SerializeField] Button _showAdButton;
[SerializeField] string rewardAndroidAdUnitId = "Rewarded_Android";
[SerializeField] string rewardiOSAdUnitId = "Rewarded_iOS";
string rewardAdUnitId = null; // This will remain null for unsupported platforms
void Awake()
{
_gameId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOSGameId
: _androidGameId;
rewardAdUnitId = (Application.platform == RuntimePlatform.IPhonePlayer)
? rewardiOSAdUnitId
: rewardAndroidAdUnitId;
Advertisement.Initialize(_gameId, _testMode, this);
rewardAdUnitId = (Application.platform == RuntimePlatform.IPhonePlayer)
? rewardiOSAdUnitId
: rewardAndroidAdUnitId;
}
public void OnInitializationComplete()
{
Debug.Log("Unity Ads initialization complete.");
LoadRewardedAd();
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
#region REWARDED ADS
public void LoadRewardedAd()
{
Debug.Log("Loading Ad: " + rewardAdUnitId);
Advertisement.Load(rewardAdUnitId, this);
}
public void ShowRewardedAd()
{
Advertisement.Show(rewardAdUnitId, this);
}
#endregion
public void OnUnityAdsAdLoaded(string adUnitId)
{
if (adUnitId.Equals(rewardAdUnitId))
{
// Configure the button to call the ShowAd() method when clicked:
//_showAdButton.onClick.AddListener(ShowRewardedAd);
// Enable the button for users to click:
//_showAdButton.interactable = true;
Debug.Log("RewardedAds Loaded");
}
}
public void OnUnityAdsShowComplete(string adUnitId, UnityAdsShowCompletionState showCompletionState)
{
if (adUnitId.Equals(rewardAdUnitId) && showCompletionState.Equals(UnityAdsShowCompletionState.COMPLETED))
{
Debug.Log("Unity Ads Rewarded Ad Completed");
// Grant a reward.
_showAdButton.onClick.RemoveAllListeners(); //with this line of code the problem is solved but shows the NullReference.
// Load another ad:
Advertisement.Load(rewardAdUnitId, this);
}
}
public void OnUnityAdsFailedToLoad(string adUnitId, UnityAdsLoadError error, string message)
{
if (adUnitId.Equals(rewardAdUnitId))
{
Debug.Log($"Error loading Ad Unit {adUnitId}: {error.ToString()} - {message}");
}
}
public void OnUnityAdsShowFailure(string adUnitId, UnityAdsShowError error, string message)
{
if (adUnitId.Equals(rewardAdUnitId))
{
Debug.Log($"Error showing Ad Unit {adUnitId}: {error.ToString()} - {message}");
}
}
public void OnUnityAdsShowStart(string adUnitId) { }
public void OnUnityAdsShowClick(string adUnitId) { }
void OnDestroy()
{
//with or without it doesn't change, it works only when the game is closed, and when reopen is working the same
//_showAdButton.onClick.RemoveAllListeners();
}
}
SOLVED!!
So, basically the script from Unity somehow has an unknown error, i couldn't explain myself how or from where... so the solution i fould was to add a bool in this case showAd = false and implemented it inside the showAd and the OnUnityAdsShowComplete functions, fortunatelly that was enough to solve the issue, now I can put the script in the button or in an AdManager and call the funtion from the button in the section OnClick() either way now is not showing neither error neither multiples with the rewards.
Hope it will be usefull for someone else.
using UnityEngine;
using UnityEngine.Advertisements;
using UnityEngine.UI;
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener, IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] string _androidGameId = "4634758";
[SerializeField] string _iOSGameId = "4634759";
[SerializeField] bool _testMode = true;
private string _gameId;
[SerializeField] Button _showAdButton; //You can remove this if want to add the function manually from OnClick()
[SerializeField] string _androidAdUnitId = "Rewarded_Android";
[SerializeField] string _iOSAdUnitId = "Rewarded_iOS";
string _adUnitId = null; // This will remain null for unsupported platforms
private bool showAd = false;
void Awake()
{
InitializeAds();
Debug.Log("Awake");
_adUnitId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOSAdUnitId
: _androidAdUnitId;
Debug.Log("the _adUnitId is: " + _adUnitId);
}
public void InitializeAds()
{
_gameId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOSGameId
: _androidGameId;
Advertisement.Initialize(_gameId, _testMode, this);
}
public void OnInitializationComplete()
{
Debug.Log("Unity Ads initialization complete.");
LoadAd();
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
public void LoadAd()
{
// IMPORTANT! Only load content AFTER initialization (in this example, initialization is handled on top of the script).
Debug.Log("Loading Ad: " + _adUnitId);
Advertisement.Load(_adUnitId, this);
}
// If the ad successfully loads, add a listener to the button and enable it:
public void OnUnityAdsAdLoaded(string adUnitId)
{
Debug.Log("Ad Loaded: " + adUnitId);
if (adUnitId.Equals(_adUnitId))
{
// Configure the button to call the ShowAd() method when clicked:
_showAdButton.onClick.AddListener(ShowAd); //You can remove this if want to add the function manually from OnClick()
// Enable the button for users to click:
_showAdButton.interactable = true; //You can remove this if want to add the function manually from OnClick()
}
}
// Implement a method to execute when the user clicks the button:
public void ShowAd()
{
if (showAd == false)
{
Debug.Log("Showing Ad");
// Disable the button:
_showAdButton.interactable = false; //You can remove this if want to add the function manually from OnClick()
// Then show the ad:
Advertisement.Show(_adUnitId, this);
_showAdButton.onClick.RemoveAllListeners(); //You can remove this if want to add the function manually from OnClick()
Debug.Log("All Listeners Removed");
showAd = true;
}
}
// Implement the Show Listener's OnUnityAdsShowComplete callback method to determine if the user gets a reward:
public void OnUnityAdsShowComplete(string adUnitId, UnityAdsShowCompletionState showCompletionState)
{
if (showAd == true)
{
if (adUnitId.Equals(_adUnitId) && showCompletionState.Equals(UnityAdsShowCompletionState.COMPLETED))
{
Debug.Log("Unity Ads Rewarded Ad Completed");
// Grant a reward.
// Load another ad:
Advertisement.Load(_adUnitId, this);
showAd = false;
}
}
}
public void OnUnityAdsFailedToLoad(string adUnitId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error loading Ad Unit {adUnitId}: {error.ToString()} - {message}");
// Use the error details to determine whether to try to load another ad.
}
public void OnUnityAdsShowFailure(string adUnitId, UnityAdsShowError error, string message)
{
Debug.Log($"Error showing Ad Unit {adUnitId}: {error.ToString()} - {message}");
// Use the error details to determine whether to try to load another ad.
}
public void OnUnityAdsShowStart(string adUnitId) { }
public void OnUnityAdsShowClick(string adUnitId) { }
}
I'm making a simple Word Builder type of game (where one player enters a word, and the other player enters a word starting with the last letter of the first player's word), and I can't get the Text to show up on both the screens.
I'm able to get the text to show up if I hard code it, like:
[PunRPC]
public void DisplayWord ()
{
MainWord.text = "Word";
}
But I can't get it to display the word a player just entered to both screens, I thought this code would word:
[PunRPC]
public void DisplayWord ()
{
MainWord.text = UsedString;
//UsedString is the word the (one of the) players just entered.
}
Any help would be greatly appreciated, thank you so much!
Here's the full code for entering a word:
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using Photon.Pun;
public class DictionaryScript : MonoBehaviourPunCallbacks
{
List<string> DictA = new List<string> () {
"a",
"aa",
"aaa",
"aah",
"aahed",
"aahing",
"aahs",
"aal",
"aalii",
"aaliis",
"aals",
"aam",
"aani",
"aardvark",
"aardvarks",
"aardwolf",
"aardwolves",
"aargh",
"aaron",
"aaronic",
"aaronical",
"aaronite",
"aaronitic",
"aarrgh",
"aarrghh",
"aaru",
"aas",
"aasvogel",
"aasvogels"};
public List<string> DictAUsed = new List<string>() { };
public string UsedString;
public string NewString;
public InputField inputField;
public Text AddedWord;
public Text MainWord;
public Text TurnText;
public Text ConnectedText;
public Button StartButton;
public Canvas OverlayCanvas;
// Start is called before the first frame update
public void Awake()
{
if (PhotonNetwork.IsMasterClient)
{
StartButton.enabled = true;
OverlayCanvas.enabled = true;
}
else
{
StartButton.enabled = false;
OverlayCanvas.enabled = true;
}
}
void Start()
{
if (PhotonNetwork.InRoom)
{
ConnectedText.text = "Connected!";
}
}
public void StartGame ()
{
photonView.RPC("CanvasDisplay", RpcTarget.All);
}
public void MyWord (string newWord)
{
string newString = newWord.ToLower();
print(newString);
if (DictA.Contains(newString) && newString[0] == MainWord.text[0] && !DictAUsed.Contains(newString))
{
UsedString = newString;
Debug.Log(UsedString);
photonView.RPC("OnInput", RpcTarget.All);
}
else
{
print("This word does not exist!");
AddedWord.text = newString + " is not a valid word!";
}
inputField.text = "";
}
[PunRPC]
public void OnInput ()
{
DictAUsed.Add(UsedString);
AddedWord.text = "The word was: " + UsedString;
photonView.RPC("DisplayWord", RpcTarget.All);
}
[PunRPC]
public void DisplayWord ()
{
MainWord.text = UsedString;
//UsedString is the word the (one of the) players just entered.
}
[PunRPC]
public void CanvasDisplay()
{
//string Alphabet = "abcdefghijklmnopqrstuvwxyz";
string Alphabet = "aaaaaaaaaaaaaaaaaaaaaaaaaa";
MainWord.text = Alphabet[Random.Range(0, 25)].ToString();
StartButton.enabled = false;
OverlayCanvas.enabled = false;
}
}
I only have words starting with 'aa' for now, I'll add all the words once I can get it working.
UsedString is not synchronized in your network => Each player might have a different value for UsedWorld at the moment the RPC get called.
Why not pass on the UsedWord as argument to OnInput and DisplayWord?
Also why is DisplayWord even called via RPC at all? Since OnInput is alreay synchronized to ALL you could simply call the method right away
...
photonView.RPC(nameof(OnInput), RpcTarget.All, UsedWord);
...
[PunRPC]
public void OnInput (string usedString)
{
DictAUsed.Add(usedString);
AddedWord.text = "The word was: " + usedString;
// since this shall happen on any client as well
// why even call it via RPC?
// OnInput is called on ALL anyway so just do it right away
DisplayWord(usedString);
}
public void DisplayWord (string usedString)
{
MainWord.text = usedString;
}
im beginner and still learning please don't hate.
So my script is located in Canvas, (Canvas -> inv -> invslot) but I need to get currentSlot int from a script in invslot gameobj., how would I do that the right way? I've tried this so far but doesn't seem to work at all.
void UpdateUI () {
for (int i = 0; i < slots.Length; i++)
{
if (i < inventory.items.Count) {
currentSlot = GetComponentsInChildren<InventoryScroll>();
slots[i] = currentSlot;
currentSlot.AddItem(inventory.items[i]);
Debug.Log ("Updating UI");
} else
{
slots[i].ClearSlot();
}
}
}
EDIT!
Here is the top of my InventoryUI, where I want to bring the int currentSlot
public Transform itemsParent;
Inventory inventory;
InventorySlot[] slots;
// Start is called before the first frame update
void Start()
{
inventory = Inventory.instance;
inventory.onItemChangedCallback += UpdateUI;
slots = itemsParent.GetComponentsInChildren<InventorySlot>();
}
But the Inventoryscroll goes this way
List<GameObject> slots = new List<GameObject>();
public int currentSlot=0;
int slotsToScroll=3;
void Start() {
foreach(Transform child in this.transform) {
slots.Add(child.gameObject);
}
}
void Update () {
if (Input.GetKeyDown(KeyCode.Alpha1)) {
currentSlot=0;
UpdateDisplay();
}
if (Input.GetAxis("Mouse ScrollWheel") >0){
if (currentSlot<slotsToScroll) {
currentSlot++;
} else {
currentSlot=0;
}
UpdateDisplay();
}
}
void UpdateDisplay() {
for (int i = 0; i < slots.Count; i++)
{
if (i==currentSlot) {
slots[i].transform.GetChild(0).gameObject.SetActive(true);
} else {
slots[i].transform.GetChild(0).gameObject.SetActive(false);
}
}
}
Inventory script
#region Singleton
public static Inventory instance;
void Awake () {
if (instance != null) {
Debug.LogWarning("More than one instance of inventory found!");
return;
}
instance = this;
}
#endregion
public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallback;
public int space = 6;
public List items = new List();
public bool Add (Item item) {
if (!item.isDefaultItem) {
if(items.Count >= space) {
Debug.Log("Not enough inventory space.");
return false;
}
items.Add(item);
if (onItemChangedCallback != null)
onItemChangedCallback.Invoke();
}
return true;
public void Remove (Item item) {
items.Remove(item);
if (onItemChangedCallback != null)
onItemChangedCallback.Invoke();
Careful, Unity has two methods:
GetComponentsInChildren
Returns all components of Type type in the GameObject or any of its children.
this returns a InventoryScroll []!
and GetComponentInChildren
Returns the component of Type type in the GameObject or any of its children using depth first search.
This returns one single InventoryScroll reference, the first one found!
Note the s!
From your description and how you use it in your code it seems like you wanted to use the latter but have an s too much.
The second mistake: From the variable name it sounds like you rather wanted to get an InventorySlot not an InventoryScroll!
So you should use
currentSlot = GetComponentInChildren<InventorySlot>();
Though it is hard to tell what your actual goal is with this code without seeing the types of slots and currentSlot.
It also appears really strange to me that you already get all slots in Start but here you overwrite
slots[i] = currentSlot;
for each i that is i < inventory.items.Coun. Also you iterate through slots.Length but you pass in inventory.izems[i] .. I don't understand what is supposed to happen here exactly.
this is basically a follow up to a previous question (Triggering an event in c# from c++ and declaring LPCWSTR). I've revised my code based on the answers and comments I have received and I solved the initial issue, which was passing the event to the GpioSetupInterruptPin from a gpio api. I don't have a lot of documentation on the api but what i'm trying to achieve is: have a form with a white label; after pressing a switch, the label turns yellow.
The problem i'm having now is the event seems to trigger as soon as it's created (the "execute" message is passed to the debug dialog and the label turns yellow) but it doesn't do anything when i toggle the switch. I was told in the last question to use WaitForSingleObject but i'm not really sure where to call it and this article only added to my confusion.
public partial class Form1 : Form
{
// P/Invoke CreateEvent and WaitForSingleObject
private void GPIO_Open() //get handle for gpio
private void GPIO_Output() //output pin declaration
private void button1_Click(object sender, EventArgs e)
{
Interrupt_Setup();
}
private void Interrupt_Setup()
{
hGPIO = GPIOapi.GpioOpenHandle(); //returns a handle to the gpio
GIPO_ON = true;
Debug.WriteLine("Driver open \n" + hGPIO);
GPIO_Output(); //set output pins
GPIO_Interrupt(Trigger); //configure interrupt
}
private void GPIO_Interrupt(string trigger)
{
bool ok;
_Main();
//INTERRUPT DECALRATION
ok = GPIOapi.GpioSetupInterruptPin(hGPIO, port6, 4, GPIOapi.INT_TRIGGER_MODE.TRIGGER_MODE_EDGE,
GPIOapi.INT_TRIGGER_POLARITY.TRIGGER_POL_HIGH_RISING, trigger, true);
Thread waitThread=new Thread(WaitForTrigger);
waitThread.Start();
if (!ok)
Debug.WriteLine("NO interrupt");
else
Debug.WriteLine("Interrupt set for:" + port6 + "04" + " at " + hGPIO);
}
public static string Trigger = "InputProcessUpdateHandler";
public static IntPtr handle = CreateEvent(IntPtr.Zero, false, false, Trigger); //used P/Invoke
private static InputProcessor inputProcessor = null;
public Color[] color =
{
Color.Orchid, Color.DarkOrchid, Color.GreenYellow, Color.CornflowerBlue, Color.SteelBlue,Color.Crimson
};
public int i = 0;
public void WaitForTrigger()
{
while(true)
{try
{
if (WaitForSingleObject(handle, 0xFFFFFFFF) == false)
{
BeginInvoke(((System.Action)(() =>label2.BackColor = color[i])));
i++;
if (i > 4)
i = 0;
}
Thread.Sleep(300);
}
catch (Exception e)
{ Debug.WriteLine("exception: " + e); }}
}
}
private void _Main()
{
inputProcessor = new InputProcessor();
ShowToggle showToggle = new ShowToggle(inputProcessor);
inputProcessor.Process(label1);
}
public class ShowToggle
{
private InputProcessor _inputProcessor = null;
public ShowToggle(InputProcessor inputProcessor)
{
_inputProcessor = inputProcessor;
_inputProcessor.updateHandledBy += InputProcessUpdateHandler;
}
private void InputProcessUpdateHandler(Label label)
{
label.BackColor = Color.Yellow;
Debug.Write("execute");
}
}
public class InputProcessor
{
public delegate void InputProcessUpdateHandler(Label label);
public event InputProcessUpdateHandler updateHandledBy = null;
public void Process(Label label)
{
if (updateHandledBy != null)
updateHandledBy(label);
}
}
If anyone could help me with this, I would be very grateful.
*** I got it working but it looks a right mess. Could anyone help me straighten it out?
You code is really confusing to me. I think what you want is something like this. Bear in mind I'm typing this into the SO text editor, so don't expect it to compile and just work - it's a guide. Consider it a step above pseudocode.
public class DeviceInterrupt
{
IntPtr m_gpio;
string m_eventName;
public event EventHandler OnInterrupt;
public DeviceInterrupt(int port)
{
// get a driver handle
m_gpio = GPIO_Open();
// generate some unique event name
m_eventName = "GPIO_evt_" + port;
// wire up the interrupt
GpioSetupInterruptPin(m_gpio, port, m_eventName, ...);
// start a listener
new Thread(EventListenerProc)
{
IsBackground = true,
Name = "gpio listener"
}
.Start();
}
public void Dispose()
{
// TODO: release the handle
}
private void EventListenerProc()
{
// create the event with the name we sent to the driver
var wh = new WaitHandle(false, m_eventName);
while (true)
{
// wait for it to get set by the driver
if (wh.WaitOne(1000))
{
// we have an interrupt
OnInterrupt.Fire(this, EventArgs.Empty);
}
}
}
}
Usage would then be something like this:
var intr = new DeviceInterrupt(4);
intr.OnInterrupt += MyHandler;
....
void MyHandler(object sender, EventArgs a)
{
Debug.WriteLine("Interrupt occurred!");
}
Note
The Compact Framework doesn't support actual named system events, so the named WaitHandle I use in my code above is not a CF-supplied WaitHandle. Instead I'm using the one from the Smart Device Framework. You could also P/Invoke to CreateEvent and WaitForSingleObject yourself.