using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; namespace SCJMapper_V2 { /// /// Maintains the complete ActionMaps - something like: /// /// /// /// /// /// /// ... /// /// /// class ActionMapsCls : List { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod( ).DeclaringType ); #region Static Part of ActionMaps // actionmap names to gather (do we need them to be cofigurable ??) public static String[] ActionMaps = { }; public static void LoadActionMaps( ) { // load actionmaps String acm = AppConfiguration.AppConfig.scActionmaps; ActionMaps = acm.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ); } #endregion Static Part of ActionMaps private String version { get; set; } private String ignoreversion { get; set; } private JoystickList m_joystickList = null; private UICustHeader m_uiCustHeader = null; private Options m_options = null; private Deviceoptions m_deviceOptions = null; // own additions for JS mapping - should not harm.. private String[] m_js; private String[] m_GUIDs; /// /// get/set jsN assignment (use 0-based index i.e. js1 -> [0]) /// public String[] jsN { get { return m_js; } } /// /// get/set jsN GUID assignment (use 0-based index i.e. js1GUID -> [0]) /// public String[] jsNGUID { get { return m_GUIDs; } } // provide access to Tuning items of the Options obj to the owner /// /// Returns the X-Tuning item /// public JoystickTuningParameter TuningX { get { return m_options.TuneX; } } /// /// Returns the Y-Tuning item /// public JoystickTuningParameter TuningY { get { return m_options.TuneY; } } /// /// Returns the Z-Tuning item /// public JoystickTuningParameter TuningZ { get { return m_options.TuneZ; } } /// /// ctor /// public ActionMapsCls( JoystickList jsList ) { version = "0"; m_joystickList = jsList; // have to save this for Reassign // create the Joystick assignments Array.Resize( ref m_js, JoystickCls.JSnum_MAX + 1 ); Array.Resize( ref m_GUIDs, JoystickCls.JSnum_MAX + 1 ); for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) { m_js[i] = ""; m_GUIDs[i] = ""; } // create options objs m_uiCustHeader = new UICustHeader( ); m_options = new Options( m_joystickList ); m_deviceOptions = new Deviceoptions( m_options ); LoadActionMaps( ); // get them from config } /// /// Copy return all ActionMaps while reassigning the JsN Tag /// /// The JsN reassign list /// The ActionMaps copy with reassigned input public ActionMapsCls ReassignJsN( Dictionary newJsList ) { ActionMapsCls newMaps = new ActionMapsCls( m_joystickList ); // full copy from 'this' newMaps.m_uiCustHeader = this.m_uiCustHeader; newMaps.m_deviceOptions = this.m_deviceOptions; newMaps.m_options = this.m_options; for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) { newMaps.jsN[i] = this.jsN[i]; newMaps.jsNGUID[i] = this.jsNGUID[i]; } foreach ( ActionMapCls am in this ) { newMaps.Add( am.ReassignJsN( newJsList ) ); } m_options.ReassignJsN( newJsList ); return newMaps; } /// /// Merge the given Map with this Map /// new ones are ignored - we don't learn from XML input for the time beeing /// /// private void Merge( ActionMapCls newAcm ) { log.Debug( "Merge - Entry" ); // do we find an actionmap like the new one in our list ? ActionMapCls ACM = this.Find( delegate( ActionMapCls acm ) { return acm.name == newAcm.name; } ); if ( ACM == null ) { ; // this.Add( newAcm ); // no, add new } else { ACM.Merge( newAcm ); // yes, merge it } } /// /// Dump the ActionMaps as partial XML nicely formatted /// /// the action as XML fragment public String toXML( ) { log.Debug( "toXML - Entry" ); AppSettings appSettings = new AppSettings( ); // handle the versioning of the actionmaps String r = "\n" ); // and dump the option contents if ( m_uiCustHeader.Count > 0 ) r += m_uiCustHeader.toXML( ) + String.Format( "\n" ); if ( m_options.Count > 0 ) r += m_options.toXML( ) + String.Format( "\n" ); if ( m_deviceOptions.Count > 0 ) r += m_deviceOptions.toXML( ) + String.Format( "\n" ); // finally the action maps foreach ( ActionMapCls amc in this ) { r += String.Format( "{0}\n", amc.toXML( ) ); } r += String.Format( "\n" ); return r; } /// /// Read an ActionMaps from XML - do some sanity check /// /// the XML action fragment /// True if an action was decoded public Boolean fromXML( String xml ) { log.Debug( "fromXML - Entry" ); // Reset those options... m_uiCustHeader = new UICustHeader( ); m_options = new Options( m_joystickList ); m_deviceOptions = new Deviceoptions( m_options ); XmlReaderSettings settings = new XmlReaderSettings( ); settings.ConformanceLevel = ConformanceLevel.Fragment; settings.IgnoreWhitespace = true; settings.IgnoreComments = true; XmlReader reader = XmlReader.Create( new StringReader( xml ), settings ); reader.Read( ); if ( reader.Name == "ActionMaps" ) { if ( reader.HasAttributes ) { version = reader["version"]; ignoreversion = reader["ignoreVersion"]; // could be either / or .. // get the joystick mapping if there is one for ( int i=0; i < JoystickCls.JSnum_MAX; i++ ) { jsN[i] = reader[String.Format( "js{0}", i + 1 )]; jsNGUID[i] = reader[String.Format( "js{0}G", i + 1 )]; } } else { return false; } } reader.Read( ); // move to next element // could be actionmap OR (AC 0.9) deviceoptions OR options while ( !reader.EOF ) { //!String.IsNullOrEmpty( x ) ) { if ( reader.Name == "actionmap" ) { String x = reader.ReadOuterXml( ); ActionMapCls acm = new ActionMapCls( ); if ( acm.fromXML( x ) ) { this.Merge( acm ); // merge list } } else if ( reader.Name == "CustomisationUIHeader" ) { String x = reader.ReadOuterXml( ); m_uiCustHeader.fromXML( x ); } else if ( reader.Name == "deviceoptions" ) { String x = reader.ReadOuterXml( ); m_deviceOptions.fromXML( x ); } else if ( reader.Name == "options" ) { String x = reader.ReadOuterXml( ); m_options.fromXML( x ); } else { reader.Read( ); } } return true; } } }