Extensiblility should be working now! extensible
Extensiblility should be working now!

// //
// VOID_Core.cs // VOID_Core.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using KSP; using KSP;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Core : VOID_Module, IVOID_Module public class VOID_Core : VOID_Module, IVOID_Module
{ {
/* /*
* Static Members * Static Members
* */ * */
protected static bool _initialized = false; protected static bool _initialized = false;
public static bool Initialized public static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected static VOID_Core _instance; protected static VOID_Core _instance;
public static VOID_Core Instance public static VOID_Core Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_Core(); _instance = new VOID_Core();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
/* /*
* Fields * Fields
* */ * */
protected string VoidName = "VOID"; protected string VoidName = "VOID";
protected string VoidVersion = "0.9.9"; protected string VoidVersion = "0.9.9";
   
[AVOID_ConfigValue("configValue")] [AVOID_ConfigValue("configValue")]
protected VOID_ConfigValue<int> configVersion = 1; protected VOID_ConfigValue<int> configVersion = 1;
   
protected List<VOID_Module> _modules = new List<VOID_Module>(); protected List<VOID_Module> _modules = new List<VOID_Module>();
  protected bool _modulesLoaded = false;
   
[AVOID_ConfigValue("mainWindowPos")] [AVOID_ConfigValue("mainWindowPos")]
protected VOID_ConfigValue<Rect> mainWindowPos = new Rect(Screen.width / 2, Screen.height / 2, 10f, 10f); protected VOID_ConfigValue<Rect> mainWindowPos = new Rect(Screen.width / 2, Screen.height / 2, 10f, 10f);
   
[AVOID_ConfigValue("mainGuiMinimized")] [AVOID_ConfigValue("mainGuiMinimized")]
protected VOID_ConfigValue<bool> mainGuiMinimized = false; protected VOID_ConfigValue<bool> mainGuiMinimized = false;
   
[AVOID_ConfigValue("configWindowPos")] [AVOID_ConfigValue("configWindowPos")]
protected VOID_ConfigValue<Rect> configWindowPos = new Rect(Screen.width / 2, Screen.height /2, 10f, 10f); protected VOID_ConfigValue<Rect> configWindowPos = new Rect(Screen.width / 2, Screen.height /2, 10f, 10f);
   
[AVOID_ConfigValue("configWindowMinimized")] [AVOID_ConfigValue("configWindowMinimized")]
protected VOID_ConfigValue<bool> configWindowMinimized = true; protected VOID_ConfigValue<bool> configWindowMinimized = true;
   
[AVOID_ConfigValue("VOIDIconPos")] [AVOID_ConfigValue("VOIDIconPos")]
protected VOID_ConfigValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f); protected VOID_ConfigValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f);
protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false); protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false); protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconTexture; protected Texture2D VOIDIconTexture;
protected string VOIDIconOnPath = "VOID/Textures/void_icon_on"; protected string VOIDIconOnPath = "VOID/Textures/void_icon_on";
protected string VOIDIconOffPath = "VOID/Textures/void_icon_off"; protected string VOIDIconOffPath = "VOID/Textures/void_icon_off";
   
protected int windowBaseID = -96518722; protected int windowBaseID = -96518722;
   
[AVOID_ConfigValue("togglePower")] [AVOID_ConfigValue("togglePower")]
public VOID_ConfigValue<bool> togglePower = true; public VOID_ConfigValue<bool> togglePower = true;
   
public bool powerAvailable = true; public bool powerAvailable = true;
   
[AVOID_ConfigValue("consumeResource")] [AVOID_ConfigValue("consumeResource")]
protected VOID_ConfigValue<bool> consumeResource = false; protected VOID_ConfigValue<bool> consumeResource = false;
   
[AVOID_ConfigValue("resourceName")] [AVOID_ConfigValue("resourceName")]
protected VOID_ConfigValue<string> resourceName = "ElectricCharge"; protected VOID_ConfigValue<string> resourceName = "ElectricCharge";
   
[AVOID_ConfigValue("resourceRate")] [AVOID_ConfigValue("resourceRate")]
protected VOID_ConfigValue<float> resourceRate = 0.2f; protected VOID_ConfigValue<float> resourceRate = 0.2f;
   
public float saveTimer = 0; public float saveTimer = 0;
   
protected string defaultSkin = "KSP window 2"; protected string defaultSkin = "KSP window 2";
protected VOID_ConfigValue<string> _skin; protected VOID_ConfigValue<string> _skin;
   
public bool configDirty; public bool configDirty;
   
/* /*
* Properties * Properties
* */ * */
public List<VOID_Module> Modules public List<VOID_Module> Modules
{ {
get get
{ {
return this._modules; return this._modules;
} }
} }
   
public GUISkin Skin public GUISkin Skin
{ {
get get
{ {
if (this._skin == null) if (this._skin == null)
{ {
this._skin = this.defaultSkin; this._skin = this.defaultSkin;
} }
return AssetBase.GetGUISkin(this._skin); return AssetBase.GetGUISkin(this._skin);
} }
} }
   
public Vessel vessel public Vessel vessel
{ {
get get
{ {
return FlightGlobals.ActiveVessel; return FlightGlobals.ActiveVessel;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
protected VOID_Core() protected VOID_Core()
{ {
this._Name = "VOID Core"; this._Name = "VOID Core";
   
this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false); this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false);
this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false); this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false);
   
// HACK: This is modular but not extensible. We need to look outside our assembly or move this to modules.  
// foreach (Type T in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())  
// {  
// Tools.PostDebugMessage (string.Format ("VOID_Core: Testing type {0}", T.Name));  
// if (typeof(IVOID_Module).IsAssignableFrom(T) &&  
// !T.IsAbstract &&  
// !typeof(VOID_Core).IsAssignableFrom(T))  
// {  
// this.LoadModule (T);  
// Tools.PostDebugMessage(string.Format("VOID_Core: Found module {0}.", T.Name));  
// }  
// }  
   
Tools.PostDebugMessage (string.Format ("VOID_Core: Loaded {0} modules.", this.Modules.Count)); Tools.PostDebugMessage (string.Format ("VOID_Core: Loaded {0} modules.", this.Modules.Count));
   
this.LoadConfig (); this.LoadConfig ();
} }
   
public void LoadModule(Type T) protected void LoadModules()
{ {
var existingModule = this.Modules.OfType<T.GetType()>(); var types = AssemblyLoader.loadedAssemblies
if (existingModule.Any()) .Select (a => a.assembly.GetExportedTypes ())
  .SelectMany (t => t)
  .Where (v => typeof(IVOID_Module).IsAssignableFrom (v)
  && !(v.IsInterface || v.IsAbstract) &&
  !typeof(VOID_Core).IsAssignableFrom (v)
  );
   
  Tools.PostDebugMessage (string.Format (
  "{0}: Checking {1} modules to check.",
  this.GetType ().Name,
  types.Count ()
  ));
  foreach (var voidType in types)
  {
  Tools.PostDebugMessage (string.Format (
  "{0}: found Type {1}",
  this.GetType ().Name,
  voidType.Name
  ));
   
  this.LoadModule(voidType);
  }
   
  this._modulesLoaded = true;
  }
   
  protected void LoadModule(Type T)
  {
  var existingModules = this._modules.Where (mod => mod.GetType ().Name == T.Name);
  if (existingModules.Any())
{ {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: refusing to load {1}: already loaded", "{0}: refusing to load {1}: already loaded",
this.GetType().Name, this.GetType().Name,
T.Name T.Name
)); ));
return; return;
} }
this._modules.Add (Activator.CreateInstance (T) as VOID_Module); this._modules.Add (Activator.CreateInstance (T) as VOID_Module);
} }
   
public void Update() public void Update()
{ {
this.saveTimer += Time.deltaTime; this.saveTimer += Time.deltaTime;
   
if (!this.guiRunning) if (!this.guiRunning)
{ {
this.StartGUI (); this.StartGUI ();
} }
   
if (!HighLogic.LoadedSceneIsFlight && this.guiRunning) if (!HighLogic.LoadedSceneIsFlight && this.guiRunning)
{ {
this.StopGUI (); this.StopGUI ();
} }
   
foreach (VOID_Module module in this.Modules) foreach (VOID_Module module in this.Modules)
{ {
if (!module.guiRunning && module.toggleActive) if (!module.guiRunning && module.toggleActive)
{ {
module.StartGUI (); module.StartGUI ();
} }
if (module.guiRunning && !module.toggleActive || !this.togglePower || !HighLogic.LoadedSceneIsFlight) if (module.guiRunning && !module.toggleActive || !this.togglePower || !HighLogic.LoadedSceneIsFlight)
{ {
module.StopGUI(); module.StopGUI();
} }
} }
   
if (this.saveTimer > 15f) if (this.saveTimer > 15f)
{ {
this.SaveConfig (); this.SaveConfig ();
this.saveTimer = 0; this.saveTimer = 0;
} }
} }
   
public void FixedUpdate() public void FixedUpdate()
{ {
if (this.consumeResource && if (this.consumeResource &&
this.vessel.vesselType != VesselType.EVA && this.vessel.vesselType != VesselType.EVA &&
TimeWarp.deltaTime != 0 TimeWarp.deltaTime != 0
) )
{ {
float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName, float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName,
this.resourceRate * TimeWarp.fixedDeltaTime); this.resourceRate * TimeWarp.fixedDeltaTime);
if (powerReceived > 0) if (powerReceived > 0)
{ {
this.powerAvailable = true; this.powerAvailable = true;
} }
else else
{ {
this.powerAvailable = false; this.powerAvailable = false;
} }
} }
} }
   
public void VOIDMainWindow(int _) public void VOIDMainWindow(int _)
{ {
GUILayout.BeginVertical(); GUILayout.BeginVertical();
if (this.powerAvailable) if (this.powerAvailable)
{ {
string str = "ON"; string str = "ON";
if (togglePower) str = "OFF"; if (togglePower) str = "OFF";
if (GUILayout.Button("Power " + str)) togglePower = !togglePower; if (GUILayout.Button("Power " + str)) togglePower = !togglePower;
if (togglePower) if (togglePower)
{ {
foreach (VOID_Module module in this.Modules) foreach (VOID_Module module in this.Modules)
{ {
module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name); module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name);
} }
} }
} }
else else
{ {
GUIStyle label_txt_red = new GUIStyle(GUI.skin.label); GUIStyle label_txt_red = new GUIStyle(GUI.skin.label);
label_txt_red.normal.textColor = Color.red; label_txt_red.normal.textColor = Color.red;
label_txt_red.alignment = TextAnchor.MiddleCenter; label_txt_red.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("-- POWER LOST --", label_txt_red); GUILayout.Label("-- POWER LOST --", label_txt_red);
} }
   
this.configWindowMinimized = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration"); this.configWindowMinimized = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration");
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
public void VOIDConfigWindow(int _) public void VOIDConfigWindow(int _)
{ {
GUILayout.BeginVertical (); GUILayout.BeginVertical ();
   
this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources"); this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources");
   
GUILayout.EndVertical (); GUILayout.EndVertical ();
GUI.DragWindow (); GUI.DragWindow ();
} }
   
public override void DrawGUI() public override void DrawGUI()
{ {
  if (!this._modulesLoaded)
  {
  this.LoadModules ();
  }
   
GUI.skin = this.Skin; GUI.skin = this.Skin;
   
int windowID = this.windowBaseID; int windowID = this.windowBaseID;
   
this.VOIDIconTexture = this.VOIDIconOff; //icon off default this.VOIDIconTexture = this.VOIDIconOff; //icon off default
if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true
if (GUI.Button(new Rect(VOIDIconPos), VOIDIconTexture, new GUIStyle())) if (GUI.Button(new Rect(VOIDIconPos), VOIDIconTexture, new GUIStyle()))
{ {
this.mainGuiMinimized = !this.mainGuiMinimized; this.mainGuiMinimized = !this.mainGuiMinimized;
} }
   
if (!this.mainGuiMinimized) if (!this.mainGuiMinimized)
{ {
Rect _mainWindowPos = this.mainWindowPos; Rect _mainWindowPos = this.mainWindowPos;
   
_mainWindowPos = GUILayout.Window ( _mainWindowPos = GUILayout.Window (
++windowID, ++windowID,
_mainWindowPos, _mainWindowPos,
this.VOIDMainWindow, this.VOIDMainWindow,
string.Join (" ", this.VoidName, this.VoidVersion), string.Join (" ", new string[] {this.VoidName, this.VoidVersion}),
GUILayout.Width (250), GUILayout.Width (250),
GUILayout.Height (50) GUILayout.Height (50)
); );
   
if (_mainWindowPos != this.mainWindowPos.value) if (_mainWindowPos != this.mainWindowPos.value)
{ {
this.mainWindowPos = _mainWindowPos; this.mainWindowPos = _mainWindowPos;
} }
} }
   
if (!this.configWindowMinimized) if (!this.configWindowMinimized)
{ {
Rect _configWindowPos = this.configWindowPos; Rect _configWindowPos = this.configWindowPos;
   
this.configWindowPos = GUILayout.Window ( this.configWindowPos = GUILayout.Window (
++windowID, ++windowID,
_configWindowPos, _configWindowPos,
this.VOIDConfigWindow, this.VOIDConfigWindow,
string.Join (" ", this.VoidName, "Configuration"), string.Join (" ", new string[] {this.VoidName, "Configuration"}),
GUILayout.Width (250), GUILayout.Width (250),
GUILayout.Height (50) GUILayout.Height (50)
); );
   
if (_configWindowPos != this.configWindowPos.value) if (_configWindowPos != this.configWindowPos.value)
{ {
this.mainWindowPos = _configWindowPos; this.mainWindowPos = _configWindowPos;
} }
} }
} }
   
public override void LoadConfig() public override void LoadConfig()
{ {
base.LoadConfig (); base.LoadConfig ();
   
foreach (VOID_Module module in this.Modules) foreach (VOID_Module module in this.Modules)
{ {
module.LoadConfig (); module.LoadConfig ();
} }
} }
   
public override void SaveConfig() public override void SaveConfig()
{ {
if (!this.configDirty) if (!this.configDirty)
{ {
return; return;
} }
   
base.SaveConfig (); base.SaveConfig ();
   
foreach (VOID_Module module in this.Modules) foreach (VOID_Module module in this.Modules)
{ {
module.SaveConfig (); module.SaveConfig ();
} }
   
this.configDirty = false; this.configDirty = false;
} }
} }
} }