You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

咨询UI向Engine项目GameSession类传递用户输入字符串的方案

解决UI向Engine的GameSession传递用户输入的方案

我来给你几个实用的解决方案,都是针对这种单向引用(UI引用Engine,Engine不引用UI)场景的解耦思路,你可以根据项目复杂度选择合适的:

方案1:直接调用GameSession的公开方法(最简单场景)

如果UI已经能获取到GameSession的实例(因为UI引用Engine,所以可以直接创建或从Engine的入口类获取),这是最直接的方式:

Engine项目的GameSession类

public class GameSession
{
    // 公开接收输入的方法,Engine内部实现处理逻辑
    public void ProcessUserInput(string input)
    {
        // 这里写你的输入处理逻辑
        Console.WriteLine($"GameSession received input: {input}");
    }
}

UI项目的Button_Click事件处理

// 持有GameSession实例(可以在UI初始化时创建或从外部注入)
private GameSession _gameSession;

public YourUIForm()
{
    InitializeComponent();
    _gameSession = new GameSession();
}

private void SubmitButton_Click(object sender, EventArgs e)
{
    string userInput = YourInputTextBox.Text;
    if (!string.IsNullOrWhiteSpace(userInput))
    {
        // 直接调用GameSession的方法传递输入
        _gameSession.ProcessUserInput(userInput);
        YourInputTextBox.Clear();
    }
}

这个方案完全满足你的需求,Engine不需要知道UI的任何细节,只需要提供公开的输入处理方法即可。

方案2:使用委托/事件实现反向通知(灵活扩展场景)

如果希望GameSession可以主动订阅输入事件,或者后续有多个组件需要响应输入,用事件/委托更灵活:

Engine项目的GameSession类

public class GameSession
{
    public GameSession()
    {
        // 可以在这里绑定内部的输入处理逻辑
        UserInputReceived += HandleUserInput;
    }

    // 定义输入事件
    public event Action<string> UserInputReceived;

    // 内部的输入处理逻辑
    private void HandleUserInput(string input)
    {
        Console.WriteLine($"Processed input: {input.ToUpper()}");
    }

    // 可选:封装事件触发逻辑,避免外部直接调用事件
    public void TriggerInput(string input)
    {
        UserInputReceived?.Invoke(input);
    }
}

UI项目的Button_Click事件处理

private GameSession _gameSession;

public YourUIForm()
{
    InitializeComponent();
    _gameSession = new GameSession();
}

private void SubmitButton_Click(object sender, EventArgs e)
{
    string userInput = YourInputTextBox.Text;
    if (!string.IsNullOrWhiteSpace(userInput))
    {
        // 直接触发GameSession的事件
        _gameSession.UserInputReceived?.Invoke(userInput);
        // 或者调用封装的触发方法
        // _gameSession.TriggerInput(userInput);
        YourInputTextBox.Clear();
    }
}

这种方式让GameSession掌握输入处理的主动权,UI只负责传递输入信号,耦合度更低。

方案3:使用抽象接口解耦(复杂/可测试场景)

如果你的项目需要扩展性(比如后续可能替换UI、或者需要单元测试GameSession),用抽象接口是最佳实践:

Engine项目定义抽象接口

// 定义输入处理的抽象接口,Engine只依赖这个接口
public interface IInputHandler
{
    void ProcessInput(string input);
}

Engine项目的GameSession类

public class GameSession
{
    private IInputHandler _inputHandler;

    // 通过构造函数注入接口实例(依赖注入思想)
    public GameSession(IInputHandler inputHandler)
    {
        _inputHandler = inputHandler;
    }

    // 或者提供设置方法
    public void SetInputHandler(IInputHandler inputHandler)
    {
        _inputHandler = inputHandler;
    }
}

UI项目实现接口

// UI实现Engine定义的接口,处理UI到GameSession的输入传递
public class UIInputHandler : IInputHandler
{
    private readonly GameSession _gameSession;

    public UIInputHandler(GameSession gameSession)
    {
        _gameSession = gameSession;
    }

    public void ProcessInput(string input)
    {
        // 可以在这里添加UI专属的输入预处理(比如去空格、格式校验)
        string cleanedInput = input.Trim();
        // 调用GameSession的核心处理逻辑
        _gameSession.ProcessUserInput(cleanedInput);
    }
}

UI项目的Button_Click事件处理

private GameSession _gameSession;
private IInputHandler _inputHandler;

public YourUIForm()
{
    InitializeComponent();
    _gameSession = new GameSession();
    _inputHandler = new UIInputHandler(_gameSession);
}

private void SubmitButton_Click(object sender, EventArgs e)
{
    string userInput = YourInputTextBox.Text;
    if (!string.IsNullOrWhiteSpace(userInput))
    {
        _inputHandler.ProcessInput(userInput);
        YourInputTextBox.Clear();
    }
}

这个方案彻底解耦了Engine和UI,Engine完全不依赖任何UI相关代码,非常适合大型项目或者需要单元测试的场景。

内容的提问来源于stack exchange,提问作者Domica

火山引擎 最新活动