MonoDroid C# Translate - c#

I am translating a java class to C#, however, I am unsure that I have done it properly. In my code below, RewardRequestListener's OnFinishedEvent should be called, however, it never hits a breakpoint or logs anything.
Here is my Java:
private RequestListener<Resource> mRequestListener = new RequestListener<Resource>() {
#Override
public void onFinished(Kiip manager, Resource response) {
if (response != null) {
if (mRewardActionToggle.isChecked()) {
manager.showResource(response);
} else {
toast("Reward Queued");
mResources.add(response);
}
} else {
toast("No Reward");
}
}
#Override
public void onError(Kiip manager, KiipException error) {
toast("error (" + error.getCode() + ") " + error.getMessage());
}
};
Here is my C#:
private static readonly string TAG = "example";
private Button mUnlockAchievement, mSaveLeaderboard, mShowNotification, mShowFullscreen, mGetActivePromos, mNewActivity;
private EditText mAchievementId, mLeaderboardId;
private static ToggleButton mPositionToggle, mRewardActionToggle;
private List<ME.Kiip.Api.Resource> mResources = new List<ME.Kiip.Api.Resource>();
private RewardRequestListener mRewardsListener;
private ActivePromosRequestListener mActivePromosListener;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
mRewardsListener = new RewardRequestListener(this);
}
class RewardRequestListener : Kiip.IRequestListener
{
ExampleActivity example = new ExampleActivity();
public RewardRequestListener(ExampleActivity example)
{
this.example = example;
}
public void OnError(Kiip p0, KiipException p1)
{
example.toast("error (" + p1.Code + ") " + p1.Message);
}
public void OnFinished(Kiip p0, Java.Lang.Object p1)
{
ME.Kiip.Api.Resource response = p1 as ME.Kiip.Api.Resource;
if (response != null)
{
if (mRewardActionToggle.Checked)
{
p0.ShowResource(response);
}
else
{
example.mResources.Add(response);
}
}
else
{
example.toast("No Reward");
}
}
public IntPtr Handle { get; set; }
public void Dispose()
{
}
}
public void OnClick(View v)
{
Kiip manager = Kiip.Instance;
switch (v.Id)
{
case Resource.Id.unlockAchievement:
manager.UnlockAchievement(mAchievementId.Text, mRewardsListener);
break;
}
}

Related

How to call keycodes from ui buttons in unity C#

This is the script.. in the starting lines you can see the usage of keycodes. I want to add UI buttons for android. When the user tap on that button it acts as Keycode.A or any Keycode which I want and I don't want to change the script. Any solution ? I am totally beginner I don't understand much of this code so don't want to change it. I got it with the free asset 2D Game Kit in which character ellen moves with pc controls. All I want is to change character controls from pc to ui buttons. Please help if I have to change the script I will get a lot of errors which I can't handle so please help.
using UnityEngine;
using UnityEngine.UIElements;
namespace Gamekit2D
{
public class PlayerInput : InputComponent, IDataPersister
{
public static PlayerInput Instance
{
get { return s_Instance; }
}
protected static PlayerInput s_Instance;
public bool HaveControl { get { return m_HaveControl; } }
public InputButton Pause = new InputButton(KeyCode.Escape, XboxControllerButtons.Menu);
public InputButton Interact = new InputButton(KeyCode.E, XboxControllerButtons.Y);
public InputButton MeleeAttack = new InputButton(KeyCode.K, XboxControllerButtons.X);
public InputButton RangedAttack = new InputButton(KeyCode.O, XboxControllerButtons.B);
public InputButton Jump = new InputButton(KeyCode.Space, XboxControllerButtons.A);
public InputAxis Horizontal = new InputAxis(KeyCode.D, KeyCode.A, XboxControllerAxes.LeftstickHorizontal);
public InputAxis Vertical = new InputAxis(KeyCode.W, KeyCode.S, XboxControllerAxes.LeftstickVertical);
[HideInInspector]
public DataSettings dataSettings;
protected bool m_HaveControl = true;
protected bool m_DebugMenuIsOpen = false;
void Awake ()
{
if (s_Instance == null)
s_Instance = this;
else
throw new UnityException("There cannot be more than one PlayerInput script. The instances are " + s_Instance.name + " and " + name + ".");
}
void OnEnable()
{
if (s_Instance == null)
s_Instance = this;
else if(s_Instance != this)
throw new UnityException("There cannot be more than one PlayerInput script. The instances are " + s_Instance.name + " and " + name + ".");
PersistentDataManager.RegisterPersister(this);
}
void OnDisable()
{
PersistentDataManager.UnregisterPersister(this);
s_Instance = null;
}
protected override void GetInputs(bool fixedUpdateHappened)
{
Pause.Get(fixedUpdateHappened, inputType);
Interact.Get(fixedUpdateHappened, inputType);
MeleeAttack.Get(fixedUpdateHappened, inputType);
RangedAttack.Get(fixedUpdateHappened, inputType);
Jump.Get(fixedUpdateHappened, inputType);
Horizontal.Get(inputType);
Vertical.Get(inputType);
if (Input.GetKeyDown(KeyCode.F12))
{
m_DebugMenuIsOpen = !m_DebugMenuIsOpen;
}
}
public override void GainControl()
{
m_HaveControl = true;
GainControl(Pause);
GainControl(Interact);
GainControl(MeleeAttack);
GainControl(RangedAttack);
GainControl(Jump);
GainControl(Horizontal);
GainControl(Vertical);
}
public override void ReleaseControl(bool resetValues = true)
{
m_HaveControl = false;
ReleaseControl(Pause, resetValues);
ReleaseControl(Interact, resetValues);
ReleaseControl(MeleeAttack, resetValues);
ReleaseControl(RangedAttack, resetValues);
ReleaseControl(Jump, resetValues);
ReleaseControl(Horizontal, resetValues);
ReleaseControl(Vertical, resetValues);
}
public void DisableMeleeAttacking()
{
MeleeAttack.Disable();
}
public void EnableMeleeAttacking()
{
MeleeAttack.Enable();
}
public void DisableRangedAttacking()
{
RangedAttack.Disable();
}
public void EnableRangedAttacking()
{
RangedAttack.Enable();
}
public DataSettings GetDataSettings()
{
return dataSettings;
}
public void SetDataSettings(string dataTag, DataSettings.PersistenceType persistenceType)
{
dataSettings.dataTag = dataTag;
dataSettings.persistenceType = persistenceType;
}
public Data SaveData()
{
return new Data<bool, bool>(MeleeAttack.Enabled, RangedAttack.Enabled);
}
public void LoadData(Data data)
{
Data<bool, bool> playerInputData = (Data<bool, bool>)data;
if (playerInputData.value0)
MeleeAttack.Enable();
else
MeleeAttack.Disable();
if (playerInputData.value1)
RangedAttack.Enable();
else
RangedAttack.Disable();
}
void OnGUI()
{
if (m_DebugMenuIsOpen)
{
const float height = 100;
GUILayout.BeginArea(new Rect(30, Screen.height - height, 200, height));
GUILayout.BeginVertical("box");
GUILayout.Label("Press F12 to close");
bool meleeAttackEnabled = GUILayout.Toggle(MeleeAttack.Enabled, "Enable Melee Attack");
bool rangeAttackEnabled = GUILayout.Toggle(RangedAttack.Enabled, "Enable Range Attack");
if (meleeAttackEnabled != MeleeAttack.Enabled)
{
if (meleeAttackEnabled)
MeleeAttack.Enable();
else
MeleeAttack.Disable();
}
if (rangeAttackEnabled != RangedAttack.Enabled)
{
if (rangeAttackEnabled)
RangedAttack.Enable();
else
RangedAttack.Disable();
}
GUILayout.EndVertical();
GUILayout.EndArea();
}
}
}
}
It's not possible. I rather advice you to directly call the functions you want when the button is pressed.

Implementing of Russian locale into Unity text to speech recognition plugin for android

Guys
I've implemented into my Unity project a plugin which can be downloaded at the link (https://github.com/HoseinPorazar/Android-Native-TTS-plugin-for-Unity-3d).
To use it you need:
1-import AndroidNativeTTS.unitypackage into your project
2-create an empty game object and rename it to tts.
3-attach test script and TextToSpeech script to tts game object.
4-add a button and set the on click event to test.Speak().
5-build project for Android platform.
After implementing the plugin to make it work it's necessary to delete in AndroidManifext.xml the line "android:label=NAtive TTS".
AndroidManifest.xml is stored in the directory "Assets\Plugin\Android\androidtts-release.aar"
When I implemented the plugin which is build to use "UK" and "US" locale, I tried to add Russian locale but unfortunately it failed.
Please see the scripts below (Test.cs and TextToSpeach.cs):
test.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test : MonoBehaviour {
TextToSpeech tts;
void Start()
{
tts = GetComponent<TextToSpeech>();
}
public void Speak()
{
tts.Speak("hello mr hosein porazar kasin", (string msg) =>
{
tts.ShowToast(msg);
});
}
public void ChangeSpeed()
{
tts.SetSpeed(0.5f);
}
public void ChangeLanguage()
{
tts.SetLanguage(TextToSpeech.Locale.UK);
}
public void ChangePitch()
{
tts.SetPitch(0.6f);
}
}
TextToSpeech.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TextToSpeech :MonoBehaviour
{
void Start()
{
}
public enum Locale
{
UK = 0,
US = 1
}
private AndroidJavaObject TTSExample = null;
private AndroidJavaObject activityContext = null;
private Locale _lang;
public Locale Language { get { return _lang; } set { SetLanguage(value); } }
private float _pitch, _speed;
public float Pitch { get{return _pitch;} set { SetPitch(value); } }
public float Speed { get{return _speed;} set { SetSpeed(value); } }
public delegate void OnErrorCallbackHandler(string error);
private OnErrorCallbackHandler _callback;
public TextToSpeech()
{
//Initialize();
}
public TextToSpeech(Locale language)
{
Initialize();
this.Language = language;
SetLanguage(this.Language);
}
public TextToSpeech(Locale language,float speed,float pitch)
{
Initialize();
this.Language = language;
this.Pitch = pitch;
this.Speed = speed;
SetLanguage(this.Language);
SetSpeed(this.Speed);
SetPitch(this.Pitch);
}
public void Speak(string toSay,OnErrorCallbackHandler callback)
{
if (TTSExample == null)
{
Initialize();
}
this._callback = callback;
TTSExample.Call("TTSMEWithCallBack", toSay, gameObject.name, "OnError");
}
public void OnError(string error)
{
if (_callback != null)
{
if (error.Length > 0)
{
_callback.Invoke(error);
}
}
ShowToast(error);
}
public void Speak(string toSay)
{
if (TTSExample == null)
{
Initialize();
}
TTSExample.Call("TTSME", toSay);
}
public void SetLanguage(Locale lan)
{
this._lang = lan;
string[] Language = new string[] {"UK","US" };
if (TTSExample == null)
{
Initialize();
}
TTSExample.Call("SetLang", Language[(int)lan]);
}
public void SetSpeed(float speed)
{
this._speed = speed;
if (TTSExample == null)
{
Initialize();
}
TTSExample.Set<float>("Speed", speed);
}
public void SetPitch(float pitch)
{
this._pitch = pitch;
if (TTSExample == null)
{
Initialize();
}
TTSExample.Set<float>("Pitch", pitch);
}
private void Initialize()
{
if (TTSExample == null)
{
using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
}
using (AndroidJavaClass pluginClass = new AndroidJavaClass("ir.hoseinporazar.androidtts.TTS"))
{
if (pluginClass != null)
{
TTSExample = pluginClass.CallStatic<AndroidJavaObject>("instance");
TTSExample.Call("setContext", activityContext);
}
}
}
}
public void ShowToast(string msg)
{
if (TTSExample == null)
{
using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
}
using (AndroidJavaClass pluginClass = new AndroidJavaClass("ir.hoseinporazar.androidtts.TTS"))
{
if (pluginClass != null)
{
TTSExample = pluginClass.CallStatic<AndroidJavaObject>("instance");
TTSExample.Call("setContext", activityContext);
activityContext.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
TTSExample.Call("showMessage", msg);
}));
}
}
}
else
{
activityContext.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
TTSExample.Call("showMessage", msg);
}));
}
}
}
I've tried to format following lines to change the language to Russian but it didn't help me:
public enum Locale
{
RU = 0,
US = 1
}
public void SetLanguage(Locale lan)
{
this._lang = lan;
string[] Language = new string[] {"RU","US" };
if (TTSExample == null)
{
Initialize();
}
TTSExample.Call("SetLang", Language[(int)lan]);
}
I also tried to contatct the developer of the plugin but it seems he was last time on github a couple years ago.
I'd really appreciate it if somebody can help me with the issue.
On the plugin homepage, the author says...
I have included 2 languages (UK,and US) if you want to use other
languages you will have to modify plugin ( with Android Studio).
So it seems you will also need to change switch statement at the bottom of the Java code here:
https://github.com/HoseinPorazar/Android-Native-TTS-plugin-for-Unity-3d/blob/master/NativeAndroidTTS/androidtts/src/main/java/ir/hoseinporazar/androidtts/TTS.java
By adding an "RU" case like this...
public void SetLang(String loc){
switch (loc){
case "UK":
if(t1!=null)
t1.setLanguage(Locale.UK);
break;
case "US":
if(t1!=null)
t1.setLanguage(Locale.US);
break;
case "RU":
if(t1!=null)
t1.setLanguage(Locale.RU);
break;
}
}

How to save multiple PlayerPrefs to cloud save

Im using google play services cloud save. I found a tutorial about how to save, but for one thing like just for highscore. I want to save multiple playerprefs, for example I have 3 ability and every one of it is saving in a playerpref so I want to save them in to the cloud and I have gold to buy these abilitys and you can buy the gold with IAP so I want to save gold too in cloud but I have no idea how to save multiple playerprefs can you help me.
My playerprefs is like this
PlayerPrefs.SetInt("Revive", revive);
PlayerPrefs.SetInt("SlowTime", slowTime);
PlayerPrefs.SetInt("Immortal", immortal);
Im changing and saving the gold after IAP purchase
PlayerPrefs.SetInt("Gold", PlayerPrefs.GetInt("Gold") + 250);
This is the Cloud Save Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GooglePlayGames;
using UnityEngine.SocialPlatforms;
using GooglePlayGames.BasicApi;
using GooglePlayGames.BasicApi.SavedGame;
using System.Text;
using System;
public class PlayGamesController : MonoBehaviour
{
public static PlayGamesController Instance { set; get; }
const string Save_Name = "Save";
bool isSaving;
bool isCloudDataLoaded = false;
private void Start()
{
if (Instance == null)
{
DontDestroyOnLoad(gameObject);
Instance = this;
}
else
{
Destroy(gameObject);
}
if (!PlayerPrefs.HasKey(Save_Name))
PlayerPrefs.SetString(Save_Name, "0");
if (!PlayerPrefs.HasKey("IsFirstTime"))
PlayerPrefs.SetInt("IsFirstTime", 1);
LoadLocal();
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder().EnableSavedGames().Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.Activate();
SignIn();
}
private void SignIn()
{
Social.localUser.Authenticate((success) => {
LoadData();
});
}
public void AddScoreToLeaderboard(string leaderboardId, long score)
{
Social.ReportScore(score, leaderboardId, (bool success) => { });
}
public void OnAchievementClick()
{
if (Social.localUser.authenticated)
{
Social.ShowAchievementsUI();
}
if (!Social.localUser.authenticated)
{
SignIn();
}
}
public void OnLeaderboardClick()
{
if (Social.localUser.authenticated)
{
Social.ShowLeaderboardUI();
}
if (!Social.localUser.authenticated)
{
SignIn();
}
}
#region Saved Games
string GameDataToString()
{
return CloudVariables.highScore.ToString();
}
void StringToGameData(string cloudData, string localData)
{
if(PlayerPrefs.GetInt("IsFirstTime") == 1)
{
PlayerPrefs.SetInt("IsFirstTime", 0);
if (int.Parse(cloudData) > int.Parse(localData))
{
PlayerPrefs.SetString(Save_Name, cloudData);
}
}
else
{
if(int.Parse(localData) > int.Parse(cloudData))
{
CloudVariables.highScore = int.Parse(localData);
AddScoreToLeaderboard(GPGSIds.leaderboard_high_score, CloudVariables.highScore);
isCloudDataLoaded = true;
SaveData();
return;
}
}
CloudVariables.highScore = int.Parse(cloudData);
isCloudDataLoaded = true;
}
void StringToGameData(string localData)
{
CloudVariables.highScore = int.Parse(localData);
}
public void LoadData()
{
if (Social.localUser.authenticated)
{
isSaving = false;
((PlayGamesPlatform)Social.Active).SavedGame.OpenWithManualConflictResolution(Save_Name, DataSource.ReadCacheOrNetwork, true, ResolveConflict, OnSavedGameOpened);
}
else
{
LoadLocal();
}
}
private void LoadLocal()
{
StringToGameData(PlayerPrefs.GetString(Save_Name));
}
public void SaveData()
{
if (!isCloudDataLoaded)
{
SaveLocal();
return;
}
if (Social.localUser.authenticated)
{
isSaving = true;
((PlayGamesPlatform)Social.Active).SavedGame.OpenWithManualConflictResolution(Save_Name, DataSource.ReadCacheOrNetwork, true, ResolveConflict, OnSavedGameOpened);
}
else
{
SaveLocal();
}
}
private void SaveLocal()
{
PlayerPrefs.SetString(Save_Name, GameDataToString());
}
private void ResolveConflict(IConflictResolver resolver, ISavedGameMetadata original, byte[] originalData, ISavedGameMetadata unmerged, byte[] unmergedData)
{
if (originalData == null)
resolver.ChooseMetadata(unmerged);
else if (unmergedData == null)
resolver.ChooseMetadata(original);
else
{
string originalStr = Encoding.ASCII.GetString(originalData);
string unmergedStr = Encoding.ASCII.GetString(unmergedData);
int originalNum = int.Parse(originalStr);
int unmergedNum = int.Parse(unmergedStr);
if(originalNum > unmergedNum)
{
resolver.ChooseMetadata(original);
return;
}
else if (unmergedNum > originalNum)
{
resolver.ChooseMetadata(unmerged);
return;
}
resolver.ChooseMetadata(original);
}
}
private void OnSavedGameOpened(SavedGameRequestStatus status, ISavedGameMetadata game)
{
if(status == SavedGameRequestStatus.Success)
{
if (!isSaving)
LoadGame(game);
else
SaveGame(game);
}
else
{
if (!isSaving)
LoadLocal();
else
SaveLocal();
}
}
private void LoadGame(ISavedGameMetadata game)
{
((PlayGamesPlatform)Social.Active).SavedGame.ReadBinaryData(game, OnSavedGameDataRead);
}
private void SaveGame(ISavedGameMetadata game)
{
string stringToSave = GameDataToString();
PlayerPrefs.SetString(Save_Name, stringToSave);
byte[] dataToSave = Encoding.ASCII.GetBytes(stringToSave);
SavedGameMetadataUpdate update = new SavedGameMetadataUpdate.Builder().Build();
((PlayGamesPlatform)Social.Active).SavedGame.CommitUpdate(game, update, dataToSave, OnSavedGameDataWritten);
}
private void OnSavedGameDataRead(SavedGameRequestStatus status, byte[] savedData)
{
if(status == SavedGameRequestStatus.Success)
{
string cloudDataString;
if (savedData.Length == 0)
cloudDataString = "0";
else
cloudDataString = Encoding.ASCII.GetString(savedData);
string localDataString = PlayerPrefs.GetString(Save_Name);
StringToGameData(cloudDataString, localDataString);
}
}
private void OnSavedGameDataWritten(SavedGameRequestStatus status, ISavedGameMetadata game)
{
}
#endregion /Saved Games
}

c# String Length Event

Basically I want to launch an event when a string reaches a specific length.
I have a Static String
Static String _Info;
So i have My Delegate that has an integer as a Parameter !
public Delegate void ReachLengthHandler(int Length);
and My event :
public event ReachLengthHandler ReachLengthEvent;
And a Method that Keep addingSome informations to that string :
public void AddInfo()
{
new Thread(() =>
{
while(true)
_Info += ""; //Basically add the inputs of the user here !
if (_Info.Length > 500)
{
if (ReachLengthEvent != null)
ReachLengthEvent(_Info.Length);
}
}).Start();
}
Do you think its the right way to do this event or there are any cleaner ways ?
EDIT :
I want this event because I want to save this string in a Database table row so I don't want to expand the possible size of a row !
As some pointed out in the comments, you may be trying to solve an instance of the XY Problem -- but assuming you're not, you are not approaching things in an object-oriented way, starting with encapsulation.
This could be a start, FWIW:
public class MaxLengthEventArgs : EventArgs
{
public MaxLengthEventArgs(string value)
{
LastAppended = value;
}
public string LastAppended { get; private set; }
}
public delegate void MaxLengthEventHandler(object sender, MaxLengthEventArgs args);
public class StringAccumulator
{
protected StringBuilder Builder { get; private set; }
public StringAccumulator(int maxLength)
{
if (maxLength < 0)
{
throw new ArgumentOutOfRangeException("maxLength", "must be positive");
}
Builder = new StringBuilder();
MaxLength = maxLength;
}
public StringAccumulator Append(string value)
{
if (!string.IsNullOrEmpty(value))
{
var sofar = value.Length + Builder.Length;
if (sofar <= MaxLength)
{
Builder.Append(value);
if ((OnMaxLength != null) && (sofar == MaxLength))
{
OnMaxLength(this, new MaxLengthEventArgs(value));
}
}
else
{
throw new InvalidOperationException("overflow");
}
}
return this;
}
public override string ToString()
{
return Builder.ToString();
}
public int MaxLength { get; private set; }
public event MaxLengthEventHandler OnMaxLength;
}
class Program
{
static void Test(object sender, MaxLengthEventArgs args)
{
var acc = (StringAccumulator)sender;
Console.WriteLine(#"max length ({0}) reached with ""{1}"" : ""{2}""", acc.MaxLength, args.LastAppended, acc.ToString());
}
public static void Main(string[] args)
{
var acc = new StringAccumulator(10);
try
{
acc.OnMaxLength += Test;
acc.Append("abc");
acc.Append("def");
acc.Append("ghij");
Console.WriteLine();
acc.Append("ouch...");
Console.WriteLine("(I won't show)");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
}
Also, keep in mind that strings in .NET are immutable.
Accumulating them using string concatenation, as you did in
_Info += ""
... isn't going to scale well (performance-wise).
'HTH,
Usually eventhandler is used with specific signature.
public delegate void ReachLengthHandler(object sender, EventArgs args);
class Program
{
public event ReachLengthHandler handler;
private const int Threshhold = 500;
public string Info
{
set
{
if (value.Length > Threshhold)
{
this.OnReachLength(null);
}
}
}
public void OnReachLength(EventArgs args)
{
this.handler?.Invoke(this, args);
}
}

How can I redirect the stdout of IronPython in C#?

I have the following:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
try
{
var strExpression = #"
import sys
sys.stdout=my.write
print 'ABC'
";
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var sourceCode = engine.CreateScriptSourceFromString(strExpression);
scope.SetVariable("my", this);
var actual = sourceCode.Execute<string>(scope);
textBox1.Text += actual;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public void write(string s)
{
textBox1.Text += s;
}
}
But I am getting an Exception that says there is no write.
What am I doing incorrectly?
You can set a stream and a textwriter directly from c#:
engine.Runtime.IO.SetOutput(stream, txtWriter);
engine.Runtime.IO.SetErrorOutput(stream, txtWriter);
To redirect the output for example you could override TextWriter class with a new one writing on your textbox.
e.g.
in my application I did an override of StreamWriter class that rises events when something is written on the stream (here just a part of the code):
public class MyEvtArgs<T> : EventArgs
{
public T Value
{
get;
private set;
}
public MyEvtArgs(T value)
{
this.Value = value;
}
}
public class EventRaisingStreamWriter : StreamWriter
{
#region Event
public event EventHandler<MyEvtArgs<string>> StringWritten;
#endregion
#region CTOR
public EventRaisingStreamWriter(Stream s):base(s)
{ }
#endregion
#region Private Methods
private void LaunchEvent(string txtWritten)
{
if (StringWritten != null)
{
StringWritten(this, new MyEvtArgs<string>(txtWritten));
}
}
#endregion
#region Overrides
public override void Write(string value)
{
base.Write(value);
LaunchEvent(value);
}
public override void Write(bool value)
{
base.Write(value);
LaunchEvent(value.ToString());
}
// here override all writing methods...
#endregion
}
Then in your application you should just do something like:
MemoryStream ms = new MemoryStream();
EventRaisingStreamWriter outputWr = new EventRaisingStreamWriter(ms);
outputWr.StringWritten += new EventHandler<MyEvtArgs<string>>(sWr_StringWritten);
var engine = Python.CreateEngine();
engine.Runtime.IO.SetOutput(ms, outputWr);
engine.CreateScriptSourceFromString("print 'hello world!'").Execute();
void sWr_StringWritten(object sender, MyEvtArgs<string> e)
{
textBox1.Text += e.Value;
}
Your example is close to working.
The problem you saw is because sys.stdout=my.write should be sys.stdout=my.
It also appears that Python expects to find a boolean softspace attribute.
I have made these two changes in the code below. Hopefully this should now work as you expected.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
try
{
var strExpression = #"
import sys
sys.stdout=my
print 'ABC' ";
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var sourceCode = engine.CreateScriptSourceFromString(strExpression);
scope.SetVariable("my", this);
var actual = sourceCode.Execute(scope);
textBox1.Text += actual;
} catch (System.Exception ex) {
MessageBox.Show(ex.ToString());
}
}
public bool softspace;
public void write(string s)
{
textBox1.Text += s;
}
}
This worked fine for me
pyRuntime = Python.CreateRuntime();
pyRuntime.IO.SetOutput(Console.OpenStandardOutput(), new UTF8Encoding(true, false));

Categories