ActionScript2 delegate 研究(下)

博客对比了Delegate和EventDispatcher的优缺点,综合两者构思了多播委托模型。介绍了事件代理句柄EventHandler、事件参数类EventArgs及其子类MouseEventArgs,还给出了多播接口和主要Event类的实现,最后用测试组件进行测试并展示了测试结果。

在上两篇中,我们研究了Macromedia Updater 2的Delegate的用法、起源、实现、优点。
然而这个Delegate可以很好的实现一个事件对应一个代理方法。但很多时候不是这样的,有更多的事物需要知道发生了这件事,然后调用自己的处理函数。比如我的一个组件,鼠标按下去的时候,有可能一个Label组件知道这个事件后改变自己的标题changeText(),同时也有可能一个MediaPlayback组件知道这个事件后要播放一个FLV视频play()……  而用Delegate,只能用一个函数来代理这些事务。然而这些事务是不同对象的方法,changeText()方法是属于Label对象的,play()方法是属于MediaPlayback对象的。当然可以把这些放在一个方法内,如下:
function EevntHandler()
{
    lbl.changeText();
    mpb.play();
}
但很多时候这些方法不能写在一个EventHandler函数中,这时我们想到了EventDispatcher,他可以让一个对象增加监听器,然后由这个对象广播事件给各个监听者。这些监听者监听到这些事件后,各自调用自己的处理事件。但Macromedia的EventDispatcher最大的一个缺点就是很多事件发生的相关信息没有传递,如鼠标点下去,很多时候需要鼠标的位置,按下的键是哪个。EventDispatcher却没有一个很好的规范去传递。

综合两者的优点。我大致构思了多播委托的模型。

Delegate改成EventHandler,构造函数稍为变化一下:

//****************************************************************************
// @FileName EventHander.as
// @Package com.flashvan.event
// @Description 事件代理句柄
// @Author aol
// @Email jeremy1982@21cn.com
// @Create 2004.10.21
// @LastChange 2004.10.21
// @History
//****************************************************************************

import com.flashvan.event.EventArgs;
import com.flashvan.event.except.Exception;

class com.flashvan.event.EventHandler extends Object
{
 /**
 Creates a functions wrapper for the original function so that it runs
 in the provided context.
 @parameter obj Context in which to run the function.
 @paramater func Function to run.
 */
 static function create(obj:Object, func:Function):Function
 {
  var f = function()
  {
   var target = arguments.callee.target;
   var func = arguments.callee.func;
   
//    
//    if(typeof(arguments[0])!= "object" && (arguments[1] instanceof EventArgs))
//     throw new Exception("参数得满足[sender:Object,e:EventArgs]的形式",this,[target,func]);

   return func.apply(target, arguments);
  };
  
  f.target = obj;
  f.func = func;

  return f;
 }

 function EventHandler(o:Object,f:Function)
 {
  obj = o
  func = f;
 }

 private var func:Function;
 private var obj:Object;

 function createEventHandler():Function
 {
  return create(obj, func);
 }
}

一个专门记录事件发生相关信息EventArgs:

//****************************************************************************
// @FileName EventArgs.as
// @Package com.flashvan.event
// @Description 事件参数类(事件发生之后传递的就是这个)
// @Author aol
// @Email jeremy1982@21cn.com
// @Create 2004.10.21
// @LastChange 2004.10.21
// @History
//****************************************************************************

class com.flashvan.event.EventArgs
{
 function EventArgs()
 {
 
 };
 
 public static function get Empty():EventArgs
 {
  return new EventArgs();
 }
 
 public function Dispose():Void
 {
  delete this;
 }
};

由EventArg继承下来的,例如专门针对鼠标事件的MouseEvntArgs
import com.flashvan.event.EventArgs;

class com.flashvan.component.core.MouseEventArgs extends EventArgs
{
 private var _clicks:Number;//鼠标被按下的次数
 
 //按下鼠标的哪个按钮
 // 0为没按, 1为左键, 2为右键, 3为滚轮
 // 要全部监测到那得用未公开函数了 ^_^
 private var _button:Number;
 
 private var _x,_y:Number;//鼠标位置
 
 private var _delta:Number;//滚轮位置
 
 private var _springTime:Number;//触发时间
 
 public function MouseEventArgs(button:Number,clicks:Number,x:Number,y:Number,delta:Number)
 {
  _springTime = getTimer();
  _button = button;
  _clicks = clicks;
  _x  = x;
  _y  = y;
  _delta  = (delta == null)? 0:delta;
  
 }
 
 public function get X():Number
 {
  return _x;
 }
 
 public function get Y():Number
 {
  return _y;
 }
 
 public function get Clicks():Number
 {
  return _clicks;
 }
 
 public function get Button():Number
 {
  return _clicks;
 }
 
 public function get Delta():Number
 {
  return _delta;
 }
 
 //触发时间
 public function get SpringTime():Number
 {
  return _springTime;
 }
}

要实现多播至少要实现这列的多播接口:
import com.flashvan.event.EventArgs;
import com.flashvan.collections.ArrayList;
import com.flashvan.event.EventHandler;

interface com.flashvan.event.IMulticastEventDelegate
{
//  public function AddEventHandler(o:Object,f:Function):Void;
 public function AddEventHandler(eh:EventHandler):Void;
 
 public function getInvocationList():ArrayList;
 
//  public function RemoveEventHandler(o:Object,f:Function):Void;
 public function RemoveEventHandler(eh:EventHandler):Void;
 
 public function RemoveAllEventHandler():Void;
 
 public function InvokeAllEventHandler(sender:Object,e:EventArgs):Void;

}

最主要的Event类实现了这个接口:

import com.flashvan.event.IMulticastEventDelegate;
import com.flashvan.collections.ArrayList;
import com.flashvan.collections.IEnumerator;
import com.flashvan.event.EventArgs;
import com.flashvan.event.EventHandler;


class com.flashvan.event.Event implements IMulticastEventDelegate
{
 private var invocationlist:ArrayList;
 
 public function Event()
 {
  invocationlist = new ArrayList();
 }
 
 
//  public function AddEventHandler(o:Object,f:Function):Void
//  {
//   invocationlist.Add({object:o,method:f});
//  }
//  public function RemoveEventHandler(o:Object,f:Function):Void
//  {
//   invocationlist.Remove({object:o,method:f});
//  }

 public function AddEventHandler(eh:EventHandler):Void
 {
  invocationlist.Add(eh);
 }
 public function RemoveEventHandler(eh:EventHandler):Void
 {
  invocationlist.Remove(eh);
 }
 
 public function RemoveAllEventHandler():Void
 {
  invocationlist.Clear();
 }
 
 public function getInvocationList():ArrayList
 {
  return invocationlist;
 }
 
//  public function InvokeAllEventHandler(sender:Object,e:EventArgs):Void
//  {
//   var enumerator:IEnumerator = invocationlist.GetEnumerator();
//   while(enumerator.MoveNext())
//   {
//    var obj:Object = enumerator.getCurrent().object;
//    var f:Function = enumerator.getCurrent().method;
//    f.apply(obj,[sender,e]);
//   }
//  }

 public function InvokeAllEventHandler(sender:Object,e:EventArgs):Void
 {
  var enumerator:IEnumerator = invocationlist.GetEnumerator();
  while(enumerator.MoveNext())
  {
   enumerator.getCurrent().createEventHandler()(sender,e);
  }
 }
}

下面用一个测试组件来测试一下:
import com.flashvan.event.Event;
import com.flashvan.event.EventArgs;
import com.flashvan.event.EventHandler;

import com.flashvan.component.core.Component;
import com.flashvan.component.core.MouseEventArgs;

class com.flashvan.test.EventTestComponent extends Component
{
 public var MouseMove:Event;
 public var MouseDown:Event;
 
 public function EventTestComponent()
 {
  MouseMove = new Event();
 }
 
 public function onMouseMove():Void
 {
  var e:MouseEventArgs = new MouseEventArgs(0,0,_xmouse,_ymouse);
  MouseMove.InvokeAllEventHandler(this,e);
 } 
}

上面的经常都已经封装好,包括上面的测试组件,实际上很多时候用户编码只需要这些:

新建一个fla文件,把做好的EventTestComponent拖到场景中命名为etc。

新建一个类com.flashvan.test.EventTest:

import com.flashvan.event.EventHandler;

import com.flashvan.component.core.Component;
import com.flashvan.component.core.MouseEventArgs;

import com.flashvan.test.EventTestComponent;

class com.flashvan.test.EventTest extends Component
{
 private var etc:EventTestComponent;
 public function EventDelegate(sender:Object,e:MouseEventArgs):Void
 {
  trace(sender);
 }
 
 public function EventDelegate2(sender:Object,e:MouseEventArgs):Void
 {
  trace(e.SpringTime);
 }
 
 public function EventTest(c:EventTestComponent)
 {
  etc = c;
  etc.MouseMove.AddEventHandler(new EventHandler(this,EventDelegate));
  etc.MouseMove.AddEventHandler(new EventHandler(this,EventDelegate2));
 }
 
 public static function main():Void
 {
  new EventTest(EventTestComponent(arguments[0]));
 }
 
}


fla文件主时间轴加上
com.flashvan.test.EventTest.main(etc);

Ctrl+ Enter测试,只要鼠标移动就会出现类似如下的结果:
_level0.etc
72
_level0.etc
1563

内容概要:本文围绕基于CNN-BiLSTM-Attention混合神经网络模型的电力负荷预测展开研究,提出一种结合卷积神经网络(CNN)、双向长短期记忆网络(BiLSTM)与注意力机制(Attention)的深度学习框架,并通过Python代码实现高精度的短期与超短期负荷预测。该模型充分利用CNN对局部特征的提取能力,捕捉负荷数据中的周期性与趋势性模式;借助BiLSTM对时间序列前后向依赖关系的建模能力,增强对动态变化的感知;并通过Attention机制自适应地聚焦关键历史时刻,提升预测准确性。文中详细阐述了数据预处理、模型结构设计、训练流程及超参数调优方法,并在真实负荷数据集上进行了实验验证,结果表明该混合模型相比传统单一模型和其他基准模型具有更优的预测性能,尤其在应对非线性、非平稳负荷波动方面表现突出。; 适合人群:具备一定Python编程能力和机器学习基础,从事电力系统分析、能源管理、智能电网或时序预测相关工作的科研人员、工程师及高校研究生。; 使用场景及目标:①应用于电网调度、电力市场出清、需求响应管理等场景下的精细化负荷预测;②为研究人员提供一套完整的、可复现的深度学习负荷预测代码框架,推动AI技术在能源领域的落地应用;③帮助理解CNN、BiLSTM与Attention模块之间的协同机制及其在时序建模中的集成方式。; 阅读建议:建议读者结合所提供的Python代码进行动手实践,重点掌握数据归一化、滑动窗口构造、模型搭建与训练技巧,并尝试在不同地区、不同季节的负荷数据上进行迁移测试,以深入理解模型泛化能力与调参策略。
内容概要:本文围绕“MATLAB具有储能的经济调度及机会约束和鲁棒优化”展开,系统研究了电力系统中融合储能技术的经济调度问题,重点探讨了机会约束规划与鲁棒优化方法在应对新能源出力不确定性、负荷波动及系统运行风险中的应用。内容涵盖风光储协同调度、多微网共享储能、电动汽车参与调度、低碳经济调度等多种典型场景,深入分析了储能的选址定容、功率协调控制、状态估计与优化调度模型。核心技术包括粒子群优化(PSO)、分布鲁棒机会约束(DRCC)、模型预测控制(MPC)、鲁棒优化、二阶锥规划(SOCP)等先进算法,并提供了基于Matlab/Simulink的完整仿真代码实现,旨在提升新型电力系统的运行灵活性、经济性与抗风险能力。; 适合人群:具备电力系统、自动化、电气工程或相关专业背景,熟悉Matlab/Simulink仿真环境与基本优化算法,从事新能源并网、微电网运行、储能系统规划、电力市场调度等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习并构建含储能的电力系统经济调度优化模型;② 掌握机会约束与鲁棒优化在处理新能源不确定性问题中的建模思路与求解方法;③ 利用提供的Matlab代码进行算法复现、仿真验证与性能对比,支撑科研项目攻关;④ 为撰写高水平学术论文、学位论文或工程优化方案提供可靠的模型参考与代码支持。; 阅读建议:建议读者结合文档中具体的案例(如风电-水电联合调度、电动汽车集群调度、多微网共享储能等)和配套的Matlab代码进行动手实践,重点关注优化模型的构建逻辑、约束条件设定与求解器配置过程,同时可关注公众号“荔枝科研社”获取完整资源包、复现教程及持续的技术支持。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值