reformat code + level load events
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ID": "194e05f445ece24ec5448d886e1334df",
|
||||
"TypeName": "FlaxEngine.SceneAsset",
|
||||
"EngineBuild": 6331,
|
||||
"EngineBuild": 6332,
|
||||
"Data": [
|
||||
{
|
||||
"ID": "194e05f445ece24ec5448d886e1334df",
|
||||
@@ -76,7 +76,7 @@
|
||||
},
|
||||
"Control": "FlaxEngine.GUI.Label",
|
||||
"Data": {
|
||||
"Text": "eFPS: 121 uTime: 33.4012628\nuFPS: 117 uTime: 0.00833330024033785\nrFPS: 120 rTime: 0\npFPS: 30 pTime: 0",
|
||||
"Text": "eFPS: 120 uTime: 0.1533353\nuFPS: -2147483648 uTime: 0.00833330024033785\nrFPS: -2147483648 rTime: 0\npFPS: -2147483648 pTime: 0",
|
||||
"TextColor": {
|
||||
"R": 1.0,
|
||||
"G": 1.0,
|
||||
@@ -123,7 +123,7 @@
|
||||
},
|
||||
"Offsets": {
|
||||
"Left": 0.0,
|
||||
"Right": 231.0,
|
||||
"Right": 284.0,
|
||||
"Top": -97.0,
|
||||
"Bottom": 64.0
|
||||
},
|
||||
|
||||
@@ -14,32 +14,16 @@ namespace Game
|
||||
None = 0,
|
||||
|
||||
/// Avoid replacing the existing playing audio source in this channel.
|
||||
ContinuePlayingExistingSource = 1,
|
||||
ContinuePlayingExistingSource = 1
|
||||
}
|
||||
|
||||
public static class AudioManager
|
||||
{
|
||||
private class AudioInfo
|
||||
{
|
||||
public AudioClip[] AudioClips;
|
||||
public int lastAudioPlayed;
|
||||
}
|
||||
private static readonly Random random = new Random();
|
||||
|
||||
private class ActorAudioChannels
|
||||
{
|
||||
public Dictionary<int, AudioSource> channelSources;
|
||||
private static readonly Dictionary<string, AudioInfo> cachedAudioInfos = new Dictionary<string, AudioInfo>();
|
||||
|
||||
public ActorAudioChannels()
|
||||
{
|
||||
channelSources = new Dictionary<int, AudioSource>();
|
||||
}
|
||||
}
|
||||
|
||||
private static Random random = new Random();
|
||||
|
||||
private static Dictionary<string, AudioInfo> cachedAudioInfos = new Dictionary<string, AudioInfo>();
|
||||
|
||||
private static Dictionary<Actor, ActorAudioChannels> actorAudioChannels =
|
||||
private static readonly Dictionary<Actor, ActorAudioChannels> actorAudioChannels =
|
||||
new Dictionary<Actor, ActorAudioChannels>();
|
||||
|
||||
public static void PlaySound(string soundName, Actor actor, Vector3 position, float volume = 1f)
|
||||
@@ -57,12 +41,14 @@ namespace Game
|
||||
PlaySound(soundName, actor, channel, AudioFlags.None, position, volume, Vector2.One);
|
||||
}
|
||||
|
||||
public static void PlaySound(string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position, float volume = 1f)
|
||||
public static void PlaySound(string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position,
|
||||
float volume = 1f)
|
||||
{
|
||||
PlaySound(soundName, actor, channel, flags, position, volume, Vector2.One);
|
||||
}
|
||||
|
||||
public static void PlaySound(string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position, float volume, Vector2 pitchRange)
|
||||
public static void PlaySound(string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position,
|
||||
float volume, Vector2 pitchRange)
|
||||
{
|
||||
AudioInfo audio = GetSound(soundName);
|
||||
if (audio.AudioClips.Length == 0)
|
||||
@@ -109,15 +95,17 @@ namespace Game
|
||||
audio.lastAudioPlayed = randomIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
audioClip = audio.AudioClips[0];
|
||||
}
|
||||
|
||||
float pitch;
|
||||
if (pitchRange[0] < pitchRange[1]) // Randomized pitch
|
||||
pitch = (float)(pitchRange[0] + (random.NextDouble() * (pitchRange[1] - pitchRange[0])));
|
||||
pitch = (float)(pitchRange[0] + random.NextDouble() * (pitchRange[1] - pitchRange[0]));
|
||||
else
|
||||
pitch = pitchRange[0];
|
||||
|
||||
var audioSource = new AudioSource();
|
||||
AudioSource audioSource = new AudioSource();
|
||||
audioSource.Clip = audioClip;
|
||||
audioSource.Position = position;
|
||||
audioSource.Parent = actor.Parent;
|
||||
@@ -126,24 +114,23 @@ namespace Game
|
||||
audioSource.Volume = volume;
|
||||
|
||||
if (volume != 1f)
|
||||
audioSource.Name += ", vol: " + volume.ToString();
|
||||
audioSource.Name += ", vol: " + volume;
|
||||
if (pitch != 1f)
|
||||
audioSource.Name += ", pitch: " + pitch.ToString();
|
||||
audioSource.Name += ", pitch: " + pitch;
|
||||
|
||||
audioSource.Play();
|
||||
Object.Destroy(audioSource, audioClip.Length);
|
||||
|
||||
if (channel > 0)
|
||||
{
|
||||
actorChannels.channelSources[channel] = audioSource;
|
||||
}
|
||||
}
|
||||
|
||||
public static async void PlaySoundDelayed(Vector2 delayRange, string soundName, Actor actor, int channel, Vector3 position, float volume = 1f)
|
||||
public static async void PlaySoundDelayed(Vector2 delayRange, string soundName, Actor actor, int channel,
|
||||
Vector3 position, float volume = 1f)
|
||||
{
|
||||
float randomDelay;
|
||||
if (delayRange[0] < delayRange[1])
|
||||
randomDelay = (float)(delayRange[0] + (random.NextDouble() * (delayRange[1] - delayRange[0])));
|
||||
randomDelay = (float)(delayRange[0] + random.NextDouble() * (delayRange[1] - delayRange[0]));
|
||||
else
|
||||
randomDelay = delayRange[0];
|
||||
|
||||
@@ -155,11 +142,12 @@ namespace Game
|
||||
PlaySound(soundName, actor, channel, AudioFlags.None, position, volume, Vector2.One);
|
||||
}
|
||||
|
||||
public static async void PlaySoundDelayed(Vector2 delayRange, string soundName, Actor actor, int channel, Vector3 position, float volume, Vector2 pitchRange)
|
||||
public static async void PlaySoundDelayed(Vector2 delayRange, string soundName, Actor actor, int channel,
|
||||
Vector3 position, float volume, Vector2 pitchRange)
|
||||
{
|
||||
float randomDelay;
|
||||
if (delayRange[0] < delayRange[1])
|
||||
randomDelay = (float)(delayRange[0] + (random.NextDouble() * (delayRange[1] - delayRange[0])));
|
||||
randomDelay = (float)(delayRange[0] + random.NextDouble() * (delayRange[1] - delayRange[0]));
|
||||
else
|
||||
randomDelay = delayRange[0];
|
||||
|
||||
@@ -171,11 +159,12 @@ namespace Game
|
||||
PlaySound(soundName, actor, channel, AudioFlags.None, position, volume, pitchRange);
|
||||
}
|
||||
|
||||
public static async void PlaySoundDelayed(Vector2 delayRange, string soundName, Actor actor, int channel, AudioFlags flags, Vector3 position, float volume, Vector2 pitchRange)
|
||||
public static async void PlaySoundDelayed(Vector2 delayRange, string soundName, Actor actor, int channel,
|
||||
AudioFlags flags, Vector3 position, float volume, Vector2 pitchRange)
|
||||
{
|
||||
float randomDelay;
|
||||
if (delayRange[0] < delayRange[1])
|
||||
randomDelay = (float)(delayRange[0] + (random.NextDouble() * (delayRange[1] - delayRange[0])));
|
||||
randomDelay = (float)(delayRange[0] + random.NextDouble() * (delayRange[1] - delayRange[0]));
|
||||
else
|
||||
randomDelay = delayRange[0];
|
||||
|
||||
@@ -219,9 +208,7 @@ namespace Game
|
||||
|
||||
if (existingAudioSource && existingAudioSource != null &&
|
||||
existingAudioSource.State == AudioSource.States.Playing)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -233,19 +220,22 @@ namespace Game
|
||||
|
||||
AudioInfo audio = new AudioInfo();
|
||||
|
||||
var workDir = Directory.GetCurrentDirectory();
|
||||
var audioBasePath = Path.Combine(workDir, "Content", "Audio");
|
||||
string workDir = Directory.GetCurrentDirectory();
|
||||
string audioBasePath = Path.Combine(workDir, "Content", "Audio");
|
||||
AudioClip audioClip = Content.Load<AudioClip>(Path.Combine(audioBasePath, soundName + ".flax"));
|
||||
if (audioClip != null)
|
||||
audio.AudioClips = new AudioClip[] { audioClip };
|
||||
{
|
||||
audio.AudioClips = new[] { audioClip };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if this audio has multiple variations
|
||||
List<AudioClip> audioClips = new List<AudioClip>();
|
||||
for (int i = 1; i<50; i++)
|
||||
var audioClips = new List<AudioClip>();
|
||||
for (int i = 1; i < 50; i++)
|
||||
{
|
||||
// TODO: make this more efficient, maybe get a list of assets and filter by name?
|
||||
AudioClip audioClipVariation = Content.Load<AudioClip>(Path.Combine(audioBasePath, soundName + "_var" + i + ".flax"));
|
||||
AudioClip audioClipVariation =
|
||||
Content.Load<AudioClip>(Path.Combine(audioBasePath, soundName + "_var" + i + ".flax"));
|
||||
if (audioClipVariation == null)
|
||||
break;
|
||||
|
||||
@@ -263,5 +253,21 @@ namespace Game
|
||||
cachedAudioInfos.Add(soundName, audio);
|
||||
return audio;
|
||||
}
|
||||
|
||||
private class AudioInfo
|
||||
{
|
||||
public AudioClip[] AudioClips;
|
||||
public int lastAudioPlayed;
|
||||
}
|
||||
|
||||
private class ActorAudioChannels
|
||||
{
|
||||
public readonly Dictionary<int, AudioSource> channelSources;
|
||||
|
||||
public ActorAudioChannels()
|
||||
{
|
||||
channelSources = new Dictionary<int, AudioSource>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,124 +1,120 @@
|
||||
using FlaxEngine;
|
||||
using Cabrito;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Cabrito;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class CameraMovement : Script
|
||||
{
|
||||
[Limit(0, 9000), Tooltip("Camera speed")]
|
||||
public float MoveSpeed { get; set; } = 400;
|
||||
public class CameraMovement : Script
|
||||
{
|
||||
private readonly InputEvent onExit = new InputEvent("Exit");
|
||||
|
||||
private float viewPitch;
|
||||
private float viewYaw;
|
||||
private float viewRoll;
|
||||
private float viewPitch;
|
||||
private float viewRoll;
|
||||
private float viewYaw;
|
||||
|
||||
private InputEvent onExit = new InputEvent("Exit");
|
||||
[Limit(0, 9000)]
|
||||
[Tooltip("Camera speed")]
|
||||
public float MoveSpeed { get; set; } = 400;
|
||||
|
||||
public override void OnAwake()
|
||||
{
|
||||
base.OnAwake();
|
||||
public override void OnAwake()
|
||||
{
|
||||
base.OnAwake();
|
||||
|
||||
onExit.Triggered += () =>
|
||||
{
|
||||
if (Console.IsSafeToQuit)
|
||||
Engine.RequestExit();
|
||||
};
|
||||
}
|
||||
onExit.Triggered += () =>
|
||||
{
|
||||
if (Console.IsSafeToQuit)
|
||||
Engine.RequestExit();
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
onExit.Dispose();
|
||||
}
|
||||
onExit.Dispose();
|
||||
}
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
var initialEulerAngles = Actor.Orientation.EulerAngles;
|
||||
viewPitch = initialEulerAngles.X;
|
||||
viewYaw = initialEulerAngles.Y;
|
||||
viewRoll = initialEulerAngles.Z;
|
||||
}
|
||||
public override void OnStart()
|
||||
{
|
||||
Vector3 initialEulerAngles = Actor.Orientation.EulerAngles;
|
||||
viewPitch = initialEulerAngles.X;
|
||||
viewYaw = initialEulerAngles.Y;
|
||||
viewRoll = initialEulerAngles.Z;
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
var camTrans = Actor.Transform;
|
||||
var rootActor = Actor.GetChild(0);
|
||||
var camera = rootActor.GetChild<Camera>();
|
||||
public override void OnUpdate()
|
||||
{
|
||||
Transform camTrans = Actor.Transform;
|
||||
Actor rootActor = Actor.GetChild(0);
|
||||
Camera camera = rootActor.GetChild<Camera>();
|
||||
|
||||
float xAxis = InputManager.GetAxisRaw("Mouse X");
|
||||
float yAxis = InputManager.GetAxisRaw("Mouse Y");
|
||||
if (xAxis != 0.0f || yAxis != 0.0f)
|
||||
{
|
||||
viewPitch += yAxis;
|
||||
viewYaw += xAxis;
|
||||
float xAxis = InputManager.GetAxisRaw("Mouse X");
|
||||
float yAxis = InputManager.GetAxisRaw("Mouse Y");
|
||||
if (xAxis != 0.0f || yAxis != 0.0f)
|
||||
{
|
||||
viewPitch += yAxis;
|
||||
viewYaw += xAxis;
|
||||
|
||||
viewPitch = Mathf.Clamp(viewPitch, -90.0f, 90.0f);
|
||||
viewPitch = Mathf.Clamp(viewPitch, -90.0f, 90.0f);
|
||||
|
||||
// root orientation must be set first
|
||||
rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0);
|
||||
camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll);
|
||||
}
|
||||
// root orientation must be set first
|
||||
rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0);
|
||||
camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll);
|
||||
}
|
||||
|
||||
float inputH = InputManager.GetAxis("Horizontal");
|
||||
float inputV = InputManager.GetAxis("Vertical");
|
||||
var move = new Vector3(inputH, 0.0f, inputV);
|
||||
float inputH = InputManager.GetAxis("Horizontal");
|
||||
float inputV = InputManager.GetAxis("Vertical");
|
||||
Vector3 move = new Vector3(inputH, 0.0f, inputV);
|
||||
|
||||
if (!move.IsZero)
|
||||
{
|
||||
move.Normalize();
|
||||
move = camera.Transform.TransformDirection(move) * MoveSpeed;
|
||||
if (!move.IsZero)
|
||||
{
|
||||
move.Normalize();
|
||||
move = camera.Transform.TransformDirection(move) * MoveSpeed;
|
||||
|
||||
{
|
||||
Vector3 delta = move * Time.UnscaledDeltaTime;
|
||||
float movementLeft = delta.Length;
|
||||
{
|
||||
Vector3 delta = move * Time.UnscaledDeltaTime;
|
||||
float movementLeft = delta.Length;
|
||||
|
||||
// TODO: check multiple times in case we get stuck in walls
|
||||
// TODO: check multiple times in case we get stuck in walls
|
||||
|
||||
float sphereRadius = 10.0f; // TODO: use collider radius
|
||||
RayCastHit[] hitInfos;
|
||||
float moveDist = delta.Length;
|
||||
Physics.SphereCastAll(Actor.Transform.Translation, sphereRadius, move.Normalized, out hitInfos,
|
||||
moveDist);
|
||||
float sphereRadius = 10.0f; // TODO: use collider radius
|
||||
RayCastHit[] hitInfos;
|
||||
float moveDist = delta.Length;
|
||||
Physics.SphereCastAll(Actor.Transform.Translation, sphereRadius, move.Normalized, out hitInfos,
|
||||
moveDist);
|
||||
|
||||
//bool nohit = true;
|
||||
float hitDistance = moveDist;
|
||||
Vector3 hitNormal = move.Normalized;
|
||||
foreach (RayCastHit hitInfo in hitInfos)
|
||||
{
|
||||
if (hitInfo.Collider.Parent == Parent)
|
||||
continue;
|
||||
//bool nohit = true;
|
||||
float hitDistance = moveDist;
|
||||
Vector3 hitNormal = move.Normalized;
|
||||
foreach (RayCastHit hitInfo in hitInfos)
|
||||
{
|
||||
if (hitInfo.Collider.Parent == Parent)
|
||||
continue;
|
||||
|
||||
if (hitInfo.Distance < hitDistance)
|
||||
{
|
||||
hitDistance = hitInfo.Distance;
|
||||
hitNormal = hitInfo.Normal;
|
||||
}
|
||||
//nohit = false;
|
||||
//break;
|
||||
}
|
||||
if (hitInfo.Distance < hitDistance)
|
||||
{
|
||||
hitDistance = hitInfo.Distance;
|
||||
hitNormal = hitInfo.Normal;
|
||||
}
|
||||
//nohit = false;
|
||||
//break;
|
||||
}
|
||||
|
||||
if (hitDistance != moveDist)
|
||||
{
|
||||
//camTrans.Translation = Vector3.Lerp(Actor.Transform.Translation, camTrans.Translation, hitDistance);
|
||||
if (hitDistance != moveDist)
|
||||
//camTrans.Translation = Vector3.Lerp(Actor.Transform.Translation, camTrans.Translation, hitDistance);
|
||||
|
||||
//projected = normal * dot(direction, normal);
|
||||
//direction = direction - projected
|
||||
//projected = normal * dot(direction, normal);
|
||||
//direction = direction - projected
|
||||
|
||||
//camTrans.Translation += hitNormal * (moveDist - hitDistance); // correct?
|
||||
//camTrans.Translation = hitNormal * (move * hitNormal); // correct?
|
||||
//camTrans.Translation = Actor.Transform.Translation;
|
||||
delta += -Vector3.Dot(delta, hitNormal) * hitNormal; // correct?
|
||||
|
||||
//camTrans.Translation += hitNormal * (moveDist - hitDistance); // correct?
|
||||
//camTrans.Translation = hitNormal * (move * hitNormal); // correct?
|
||||
//camTrans.Translation = Actor.Transform.Translation;
|
||||
delta += -Vector3.Dot(delta, hitNormal) * hitNormal; // correct?
|
||||
}
|
||||
camTrans.Translation += delta;
|
||||
}
|
||||
}
|
||||
|
||||
camTrans.Translation += delta;
|
||||
}
|
||||
}
|
||||
|
||||
Actor.Transform = camTrans;
|
||||
}
|
||||
}
|
||||
Actor.Transform = camTrans;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,34 @@
|
||||
using System;
|
||||
using System.Runtime;
|
||||
using Cabrito;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
/// <summary>
|
||||
/// CameraRender Script.
|
||||
/// CameraRender Script.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
public class CameraRender : PostProcessEffect
|
||||
{
|
||||
public Camera camera;
|
||||
public Material material;
|
||||
|
||||
private GPUTexture texture;
|
||||
private GPUTexture texture2;
|
||||
private bool lastEnabled;
|
||||
public Material material;
|
||||
|
||||
private MaterialInstance materialInstance;
|
||||
private SceneRenderTask sceneTask;
|
||||
private SceneRenderTask sceneTask2;
|
||||
|
||||
private GPUTexture texture;
|
||||
private GPUTexture texture2;
|
||||
|
||||
public override PostProcessEffectLocation Location => PostProcessEffectLocation.Default;
|
||||
public override int Order => 110;
|
||||
public override bool CanRender => camera.IsActive;
|
||||
|
||||
private void CreateTextures(int width, int height)
|
||||
{
|
||||
var textureDesc = GPUTextureDescription.New2D(width, height, PixelFormat.R8G8B8A8_UNorm);
|
||||
GPUTextureDescription textureDesc = GPUTextureDescription.New2D(width, height, PixelFormat.R8G8B8A8_UNorm);
|
||||
|
||||
// Prepare texture and SceneRenderTask for viewmodel camera
|
||||
if (texture == null)
|
||||
@@ -82,11 +86,8 @@ namespace Game
|
||||
Destroy(ref texture2);
|
||||
}
|
||||
|
||||
public override PostProcessEffectLocation Location => PostProcessEffectLocation.Default;
|
||||
public override int Order => 110;
|
||||
public override bool CanRender => camera.IsActive;
|
||||
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input,
|
||||
GPUTexture output)
|
||||
{
|
||||
if (texture == null || texture2 == null)
|
||||
return;
|
||||
@@ -94,13 +95,12 @@ namespace Game
|
||||
Renderer.DrawPostFxMaterial(context, ref renderContext, materialInstance, output, input.View());
|
||||
}
|
||||
|
||||
private bool lastEnabled;
|
||||
public override void OnUpdate()
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
if (Input.GetKeyDown(KeyboardKeys.F7))
|
||||
{
|
||||
var physicsSettings = GameSettings.Load<PhysicsSettings>();
|
||||
PhysicsSettings physicsSettings = GameSettings.Load<PhysicsSettings>();
|
||||
physicsSettings.EnableSubstepping = !physicsSettings.EnableSubstepping;
|
||||
GameSettings.Save(physicsSettings);
|
||||
//GameSettings.Apply();
|
||||
@@ -130,4 +130,4 @@ namespace Game
|
||||
//OnAwake();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,19 @@
|
||||
using System;
|
||||
using System.Runtime;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class CameraSpring : Script
|
||||
{
|
||||
private Vector3 targetOffset;
|
||||
private bool lastGround;
|
||||
private Vector3 lastPosition;
|
||||
|
||||
public float speed = 240f;
|
||||
public float percY;
|
||||
|
||||
private Actor playerActor;
|
||||
private Actor viewModelHolder;
|
||||
private PlayerMovement playerMovement;
|
||||
|
||||
private bool lastGround;
|
||||
public float speed = 240f;
|
||||
private Vector3 targetOffset;
|
||||
private Actor viewModelHolder;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
@@ -62,7 +56,9 @@ namespace Game
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePosition(position);
|
||||
}
|
||||
|
||||
lastPosition = position;
|
||||
lastGround = playerMovement.onGround;
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class WeaponSway : Script
|
||||
{
|
||||
public float swaySpeed = 3000f;
|
||||
private Actor cameraHolder;
|
||||
|
||||
private Actor rootActor;
|
||||
private Actor cameraHolder;
|
||||
public float swaySpeed = 3000f;
|
||||
|
||||
private float timeRemainder;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
rootActor = Actor.Parent.GetChild("RootActor");
|
||||
@@ -25,7 +26,6 @@ namespace Game
|
||||
return yawRoll * pitch;
|
||||
}
|
||||
|
||||
private float timeRemainder = 0f;
|
||||
public override void OnLateUpdate()
|
||||
{
|
||||
Quaternion rotation = GetRotation();
|
||||
@@ -65,7 +65,7 @@ namespace Game
|
||||
float percZ = Mathf.Abs(deltaZ) / maxAngle;
|
||||
float minSpeed = swaySpeedScaled * 0.00001f * 0f;
|
||||
|
||||
Func<float, float> fun = (f) => Mathf.Pow(f, 1.3f);
|
||||
Func<float, float> fun = f => Mathf.Pow(f, 1.3f);
|
||||
|
||||
angles.X = Mathf.MoveTowardsAngle(angles.X, targetAngles.X,
|
||||
Math.Max(swaySpeedScaled * fun(percX), minSpeed));
|
||||
@@ -74,9 +74,10 @@ namespace Game
|
||||
angles.Z = Mathf.MoveTowardsAngle(angles.Z, targetAngles.Z,
|
||||
Math.Max(swaySpeedScaled * fun(percZ), minSpeed));
|
||||
} while (remaining > minTime);
|
||||
|
||||
timeRemainder -= remaining;
|
||||
|
||||
Actor.LocalOrientation = Quaternion.Euler(angles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
// Holds common miscellaneous Console variables and commands
|
||||
public static class CommonCommands
|
||||
{
|
||||
[ConsoleCommand("")]
|
||||
public static void NullCommand()
|
||||
{
|
||||
}
|
||||
// Holds common miscellaneous Console variables and commands
|
||||
public static class CommonCommands
|
||||
{
|
||||
[ConsoleVariable("developer")]
|
||||
public static string Developer
|
||||
{
|
||||
get => Console.DebugVerbosity.ToString();
|
||||
set
|
||||
{
|
||||
if (int.TryParse(value, out int intValue) && intValue >= 0)
|
||||
Console.DebugVerbosity = intValue;
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("echo")]
|
||||
public static void EchoCommand()
|
||||
{
|
||||
Console.Print("nothing");
|
||||
}
|
||||
[ConsoleCommand("")]
|
||||
public static void NullCommand()
|
||||
{
|
||||
}
|
||||
|
||||
[ConsoleCommand("echo")]
|
||||
public static void EchoCommand(string[] text)
|
||||
{
|
||||
Console.Print(string.Join(" ", text));
|
||||
}
|
||||
[ConsoleCommand("echo")]
|
||||
public static void EchoCommand()
|
||||
{
|
||||
Console.Print("nothing");
|
||||
}
|
||||
|
||||
[ConsoleCommand("debugthrow")]
|
||||
public static void DebugThrowCommand(string[] text)
|
||||
{
|
||||
throw new Exception(string.Join(" ", text));
|
||||
}
|
||||
[ConsoleCommand("echo")]
|
||||
public static void EchoCommand(string[] text)
|
||||
{
|
||||
Console.Print(string.Join(" ", text));
|
||||
}
|
||||
|
||||
[ConsoleVariable("developer")]
|
||||
public static string Developer
|
||||
{
|
||||
get
|
||||
{
|
||||
return Console.DebugVerbosity.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (int.TryParse(value, out int intValue) && intValue >= 0)
|
||||
Console.DebugVerbosity = intValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
[ConsoleCommand("debugthrow")]
|
||||
public static void DebugThrowCommand(string[] text)
|
||||
{
|
||||
throw new Exception(string.Join(" ", text));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,472 +3,507 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using FlaxEngine;
|
||||
using Debug = System.Diagnostics.Debug;
|
||||
using FlaxEditor;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
public class ConsoleLine
|
||||
{
|
||||
public string content;
|
||||
public class ConsoleLine
|
||||
{
|
||||
public string content;
|
||||
|
||||
internal ConsoleLine(string line)
|
||||
{
|
||||
content = line;
|
||||
}
|
||||
internal ConsoleLine(string line)
|
||||
{
|
||||
content = line;
|
||||
}
|
||||
|
||||
public static implicit operator string(ConsoleLine line) => line.content;
|
||||
public static explicit operator ConsoleLine(string line) => new ConsoleLine(line);
|
||||
public static implicit operator string(ConsoleLine line)
|
||||
{
|
||||
return line.content;
|
||||
}
|
||||
|
||||
public override string ToString() => content.ToString();
|
||||
}
|
||||
public static explicit operator ConsoleLine(string line)
|
||||
{
|
||||
return new ConsoleLine(line);
|
||||
}
|
||||
|
||||
public static class Console
|
||||
{
|
||||
private static ConsoleInstance instance;
|
||||
public override string ToString()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (instance != null)
|
||||
return;
|
||||
public static class Console
|
||||
{
|
||||
private static ConsoleInstance instance;
|
||||
|
||||
Destroy();
|
||||
instance = new ConsoleInstance();
|
||||
instance.InitConsoleSubsystems();
|
||||
// Returns if Console window open right now.
|
||||
public static bool IsOpen => instance.IsOpen;
|
||||
|
||||
// For debugging only: Returns true when Console was not closed during the same frame.
|
||||
// Needed when Escape-key both closes the console and exits the game.
|
||||
public static bool IsSafeToQuit => instance.IsSafeToQuit;
|
||||
|
||||
// Called when Console is opened.
|
||||
public static Action OnOpen
|
||||
{
|
||||
get => instance.OnOpen;
|
||||
set => instance.OnOpen = value;
|
||||
}
|
||||
|
||||
// Called when Console is closed.
|
||||
public static Action OnClose
|
||||
{
|
||||
get => instance.OnClose;
|
||||
set => instance.OnClose = value;
|
||||
}
|
||||
|
||||
// Called when a line of text was printed in Console.
|
||||
public static Action<string> OnPrint
|
||||
{
|
||||
get => instance.OnPrint;
|
||||
set => instance.OnPrint = value;
|
||||
}
|
||||
|
||||
public static bool ShowExecutedLines => instance.ShowExecutedLines;
|
||||
|
||||
public static int DebugVerbosity
|
||||
{
|
||||
get => instance.DebugVerbosity;
|
||||
set => instance.DebugVerbosity = value;
|
||||
}
|
||||
|
||||
public static string LinePrefix => instance.LinePrefix;
|
||||
|
||||
public static IReadOnlyCollection<ConsoleLine> Lines => instance.Lines;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (instance != null)
|
||||
return;
|
||||
|
||||
Destroy();
|
||||
instance = new ConsoleInstance();
|
||||
instance.InitConsoleSubsystems();
|
||||
|
||||
#if FLAX_EDITOR
|
||||
FlaxEditor.ScriptsBuilder.ScriptsReload += Destroy;
|
||||
FlaxEditor.Editor.Instance.StateMachine.StateChanged += OnEditorStateChanged;
|
||||
ScriptsBuilder.ScriptsReload += Destroy;
|
||||
Editor.Instance.StateMachine.StateChanged += OnEditorStateChanged;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public static void Destroy()
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
instance.Dispose();
|
||||
instance = null;
|
||||
public static void Destroy()
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
instance.Dispose();
|
||||
instance = null;
|
||||
|
||||
#if FLAX_EDITOR
|
||||
FlaxEditor.ScriptsBuilder.ScriptsReload -= Destroy;
|
||||
FlaxEditor.Editor.Instance.StateMachine.StateChanged -= OnEditorStateChanged;
|
||||
ScriptsBuilder.ScriptsReload -= Destroy;
|
||||
Editor.Instance.StateMachine.StateChanged -= OnEditorStateChanged;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
private static void OnEditorStateChanged()
|
||||
{
|
||||
if (!FlaxEditor.Editor.Instance.StateMachine.IsPlayMode)
|
||||
{
|
||||
// Clear console buffer when leaving play mode
|
||||
if (instance != null)
|
||||
Console.Clear();
|
||||
}
|
||||
}
|
||||
private static void OnEditorStateChanged()
|
||||
{
|
||||
if (!Editor.Instance.StateMachine.IsPlayMode)
|
||||
// Clear console buffer when leaving play mode
|
||||
if (instance != null)
|
||||
Clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Returns if Console window open right now.
|
||||
public static bool IsOpen => instance.IsOpen;
|
||||
|
||||
// For debugging only: Returns true when Console was not closed during the same frame.
|
||||
// Needed when Escape-key both closes the console and exits the game.
|
||||
public static bool IsSafeToQuit => instance.IsSafeToQuit;
|
||||
|
||||
// Called when Console is opened.
|
||||
public static Action OnOpen
|
||||
{
|
||||
get { return instance.OnOpen; }
|
||||
set { instance.OnOpen = value; }
|
||||
}
|
||||
|
||||
// Called when Console is closed.
|
||||
public static Action OnClose
|
||||
{
|
||||
get { return instance.OnClose; }
|
||||
set { instance.OnClose = value; }
|
||||
}
|
||||
|
||||
// Called when a line of text was printed in Console.
|
||||
public static Action<string> OnPrint
|
||||
{
|
||||
get { return instance.OnPrint; }
|
||||
set { instance.OnPrint = value; }
|
||||
}
|
||||
|
||||
public static bool ShowExecutedLines => instance.ShowExecutedLines;
|
||||
public static int DebugVerbosity
|
||||
{
|
||||
get => instance.DebugVerbosity;
|
||||
set => instance.DebugVerbosity = value;
|
||||
}
|
||||
|
||||
public static string LinePrefix => instance.LinePrefix;
|
||||
|
||||
public static IReadOnlyCollection<ConsoleLine> Lines => instance.Lines;
|
||||
|
||||
public static string GetBufferHistory(int index) => instance.GetBufferHistory(index);
|
||||
|
||||
// Echoes text to Console
|
||||
public static void Print(string text) => instance.Print(text);
|
||||
|
||||
// Echoes warning text to Console
|
||||
public static void PrintWarning(string text) => instance.PrintWarning(text);
|
||||
|
||||
// Echoes error text to Console
|
||||
public static void PrintError(string text) => instance.PrintError(text);
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
public static void PrintDebug(string text) => instance.PrintDebug(1, false, text);
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
public static void PrintDebug(int verbosity, string text) => instance.PrintDebug(verbosity, false, text);
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
public static void PrintDebug(int verbosity, bool noRepeat, string text) => instance.PrintDebug(verbosity, noRepeat, text);
|
||||
|
||||
// Opens the Console
|
||||
public static void Open() => instance.Open();
|
||||
|
||||
// Closes the Console
|
||||
public static void Close() => instance.Close();
|
||||
|
||||
// Clears the content of the Console
|
||||
public static void Clear() => instance.Clear();
|
||||
|
||||
public static void Execute(string str, bool bufferInput = false) => instance.Execute(str, bufferInput);
|
||||
|
||||
public static string GetVariable(string variableName) => instance.GetVariable(variableName);
|
||||
}
|
||||
|
||||
public class ConsoleInstance : IDisposable
|
||||
{
|
||||
public bool IsOpen { get; internal set; } = true;
|
||||
|
||||
public bool IsSafeToQuit
|
||||
{
|
||||
get { return stopwatch.Elapsed.TotalSeconds > 0.1; }
|
||||
}
|
||||
|
||||
private Stopwatch stopwatch = Stopwatch.StartNew();
|
||||
|
||||
public Action OnOpen;
|
||||
public Action OnClose;
|
||||
public Action<string> OnPrint;
|
||||
|
||||
public bool ShowExecutedLines = true;
|
||||
public int DebugVerbosity { get; set; } = 1;
|
||||
public string LinePrefix { get; internal set; } = "]";
|
||||
|
||||
//private static List<string> consoleLines = new List<string>();
|
||||
private List<ConsoleLine> consoleLines = new List<ConsoleLine>();
|
||||
private Dictionary<string, ConsoleCommand> consoleCommands = new Dictionary<string, ConsoleCommand>();
|
||||
private Dictionary<string, ConsoleVariable> consoleVariables = new Dictionary<string, ConsoleVariable>();
|
||||
private List<string> consoleBufferHistory = new List<string>();
|
||||
|
||||
internal ConsoleInstance()
|
||||
{
|
||||
}
|
||||
|
||||
// Initializes the Console system.
|
||||
internal void InitConsoleSubsystems()
|
||||
{
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
Assembly[] assemblies = currentDomain.GetAssemblies();
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
// Skip common assemblies
|
||||
var assemblyName = assembly.GetName().Name;
|
||||
if (assemblyName == "System" ||
|
||||
assemblyName.StartsWith("System.") ||
|
||||
assemblyName.StartsWith("Mono.") ||
|
||||
assemblyName == "mscorlib" ||
|
||||
assemblyName == "Newtonsoft.Json" ||
|
||||
assemblyName.StartsWith("FlaxEngine.") ||
|
||||
assemblyName.StartsWith("JetBrains.") ||
|
||||
assemblyName.StartsWith("Microsoft.") ||
|
||||
assemblyName.StartsWith("nunit."))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
Dictionary<string, ConsoleCommand> cmdParsed = new Dictionary<string, ConsoleCommand>();
|
||||
Dictionary<string, List<MethodInfo>> cmdMethods = new Dictionary<string, List<MethodInfo>>();
|
||||
MethodInfo cmdInitializer = null;
|
||||
|
||||
foreach (MethodInfo method in type.GetMethods())
|
||||
{
|
||||
if (!method.IsStatic)
|
||||
continue;
|
||||
|
||||
Attribute[] attributes = Attribute.GetCustomAttributes(method);
|
||||
|
||||
foreach (Attribute attr in attributes)
|
||||
{
|
||||
if (attr is ConsoleCommandAttribute cmdAttribute)
|
||||
{
|
||||
//Console.Print("found cmd '" + cmdAttribute.name + "' bound to field '" + method.Name + "'");
|
||||
|
||||
// Defer constructing the command until we have parsed all the methods for it in this assembly.
|
||||
|
||||
List<MethodInfo> methods;
|
||||
if (!cmdMethods.TryGetValue(cmdAttribute.name, out methods))
|
||||
{
|
||||
methods = new List<MethodInfo>();
|
||||
cmdMethods.Add(cmdAttribute.name, methods);
|
||||
}
|
||||
|
||||
methods.Add(method);
|
||||
|
||||
ConsoleCommand cmd = new ConsoleCommand(cmdAttribute.name, null);
|
||||
if (!cmdParsed.ContainsKey(cmdAttribute.name))
|
||||
cmdParsed.Add(cmdAttribute.name, cmd);
|
||||
foreach (var alias in cmdAttribute.aliases)
|
||||
{
|
||||
if (!cmdParsed.ContainsKey(alias))
|
||||
cmdParsed.Add(alias, cmd);
|
||||
|
||||
List<MethodInfo> aliasMethods;
|
||||
if (!cmdMethods.TryGetValue(alias, out aliasMethods))
|
||||
{
|
||||
aliasMethods = new List<MethodInfo>();
|
||||
cmdMethods.Add(alias, aliasMethods);
|
||||
}
|
||||
|
||||
aliasMethods.Add(method);
|
||||
}
|
||||
}
|
||||
else if (attr is ConsoleSubsystemInitializer)
|
||||
{
|
||||
cmdInitializer = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kv in cmdParsed)
|
||||
{
|
||||
var methods = cmdMethods[kv.Key];
|
||||
var definition = kv.Value;
|
||||
|
||||
ConsoleCommand cmd = new ConsoleCommand(definition.name, methods.ToArray());
|
||||
consoleCommands.Add(kv.Key, cmd);
|
||||
}
|
||||
|
||||
foreach (FieldInfo field in type.GetFields())
|
||||
{
|
||||
if (!field.IsStatic)
|
||||
continue;
|
||||
|
||||
Attribute[] attributes = Attribute.GetCustomAttributes(field);
|
||||
|
||||
foreach (Attribute attr in attributes)
|
||||
{
|
||||
if (attr is ConsoleVariableAttribute cvarAttribute)
|
||||
{
|
||||
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
|
||||
consoleVariables.Add(cvarAttribute.name,
|
||||
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, field));
|
||||
foreach (var alias in cvarAttribute.aliases)
|
||||
consoleVariables.Add(alias,
|
||||
new ConsoleVariable(cvarAttribute.name,
|
||||
cvarAttribute.flags | ConsoleFlags.NoSerialize, field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PropertyInfo prop in type.GetProperties())
|
||||
{
|
||||
MethodInfo getter = prop.GetGetMethod();
|
||||
MethodInfo setter = prop.GetSetMethod();
|
||||
if (getter == null || setter == null || !getter.IsStatic || !setter.IsStatic)
|
||||
continue;
|
||||
|
||||
Attribute[] attributes = Attribute.GetCustomAttributes(prop);
|
||||
|
||||
foreach (Attribute attr in attributes)
|
||||
{
|
||||
if (attr is ConsoleVariableAttribute cvarAttribute)
|
||||
{
|
||||
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
|
||||
consoleVariables.Add(cvarAttribute.name,
|
||||
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, getter, setter));
|
||||
foreach (var alias in cvarAttribute.aliases)
|
||||
consoleVariables.Add(alias,
|
||||
new ConsoleVariable(cvarAttribute.name,
|
||||
cvarAttribute.flags | ConsoleFlags.NoSerialize, getter, setter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdInitializer != null)
|
||||
{
|
||||
Console.PrintDebug(2, "Initializing " + type.Name);
|
||||
cmdInitializer.Invoke(null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<ConsoleLine> Lines
|
||||
{
|
||||
get => consoleLines.AsReadOnly();
|
||||
}
|
||||
|
||||
public string GetBufferHistory(int index)
|
||||
{
|
||||
if (consoleBufferHistory.Count == 0)
|
||||
return null;
|
||||
|
||||
if (index > consoleBufferHistory.Count - 1 || index < 0)
|
||||
return null;
|
||||
|
||||
return consoleBufferHistory[index];
|
||||
}
|
||||
|
||||
// Echoes text to Console
|
||||
public void Print(string text)
|
||||
{
|
||||
debugLastLine = text;
|
||||
|
||||
foreach (var line in text.Split(new[] { '\n' }))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Echoes warning text to Console
|
||||
public void PrintWarning(string text)
|
||||
{
|
||||
foreach (var line in text.Split(new[] { '\n' }))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Echoes error text to Console
|
||||
public void PrintError(string text)
|
||||
{
|
||||
foreach (var line in text.Split(new[] { '\n' }))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
Debugger.Break();
|
||||
else
|
||||
throw new Exception(text);
|
||||
}
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
private string debugLastLine = "";
|
||||
public void PrintDebug(int verbosity, bool noRepeat, string text)
|
||||
{
|
||||
if (DebugVerbosity < verbosity)
|
||||
return;
|
||||
|
||||
if (noRepeat)
|
||||
{
|
||||
if (debugLastLine.Length == text.Length && debugLastLine == text)
|
||||
return;
|
||||
}
|
||||
|
||||
debugLastLine = text;
|
||||
|
||||
foreach (var line in text.Split(new[] { '\n' }))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Opens the Console
|
||||
public void Open()
|
||||
{
|
||||
if (IsOpen)
|
||||
return;
|
||||
|
||||
IsOpen = true;
|
||||
OnOpen?.Invoke();
|
||||
}
|
||||
|
||||
// Closes the Console
|
||||
public void Close()
|
||||
{
|
||||
if (!IsOpen)
|
||||
return;
|
||||
|
||||
IsOpen = false;
|
||||
OnClose?.Invoke();
|
||||
|
||||
stopwatch.Restart();
|
||||
}
|
||||
|
||||
// Clears the content of the Console
|
||||
public void Clear()
|
||||
{
|
||||
consoleLines.Clear();
|
||||
}
|
||||
|
||||
public void Execute(string str, bool bufferInput = false)
|
||||
{
|
||||
if (bufferInput)
|
||||
consoleBufferHistory.Insert(0, str);
|
||||
|
||||
str = str.Trim();
|
||||
|
||||
if (ShowExecutedLines)
|
||||
Console.Print(LinePrefix + str);
|
||||
|
||||
string[] strs = str.Split(' ');
|
||||
string execute = strs[0];
|
||||
string executeLower = execute.ToLowerInvariant();
|
||||
string value = strs.Length > 1 ? str.Substring(execute.Length + 1) : null;
|
||||
|
||||
//Console.PrintDebug("Executed '" + execute + "' with params: '" + value + "'");
|
||||
|
||||
if (consoleCommands.TryGetValue(executeLower, out ConsoleCommand cmd))
|
||||
{
|
||||
string[] values = strs.Skip(1).ToArray();
|
||||
if (values.Length > 0)
|
||||
cmd.Invoke(values);
|
||||
else
|
||||
cmd.Invoke();
|
||||
//Console.Print("Command bound to '" + execute + "' is '" + cmd.method.Name + "'");
|
||||
}
|
||||
else if (consoleVariables.TryGetValue(executeLower, out ConsoleVariable cvar))
|
||||
{
|
||||
if (value != null)
|
||||
cvar.SetValue(value);
|
||||
|
||||
Console.Print("'" + execute + "' is '" + cvar.GetValueString() + "'");
|
||||
}
|
||||
else
|
||||
Console.Print("Unknown command '" + execute + "'");
|
||||
}
|
||||
|
||||
public string GetVariable(string variableName)
|
||||
{
|
||||
if (consoleVariables.TryGetValue(variableName, out ConsoleVariable cvar))
|
||||
{
|
||||
string value = cvar.GetValueString();
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static string GetBufferHistory(int index)
|
||||
{
|
||||
return instance.GetBufferHistory(index);
|
||||
}
|
||||
|
||||
// Echoes text to Console
|
||||
public static void Print(string text)
|
||||
{
|
||||
instance.Print(text);
|
||||
}
|
||||
|
||||
// Echoes warning text to Console
|
||||
public static void PrintWarning(string text)
|
||||
{
|
||||
instance.PrintWarning(text);
|
||||
}
|
||||
|
||||
// Echoes error text to Console
|
||||
public static void PrintError(string text)
|
||||
{
|
||||
instance.PrintError(text);
|
||||
}
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
public static void PrintDebug(string text)
|
||||
{
|
||||
instance.PrintDebug(1, false, text);
|
||||
}
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
public static void PrintDebug(int verbosity, string text)
|
||||
{
|
||||
instance.PrintDebug(verbosity, false, text);
|
||||
}
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
public static void PrintDebug(int verbosity, bool noRepeat, string text)
|
||||
{
|
||||
instance.PrintDebug(verbosity, noRepeat, text);
|
||||
}
|
||||
|
||||
// Opens the Console
|
||||
public static void Open()
|
||||
{
|
||||
instance.Open();
|
||||
}
|
||||
|
||||
// Closes the Console
|
||||
public static void Close()
|
||||
{
|
||||
instance.Close();
|
||||
}
|
||||
|
||||
// Clears the content of the Console
|
||||
public static void Clear()
|
||||
{
|
||||
instance.Clear();
|
||||
}
|
||||
|
||||
public static void Execute(string str, bool bufferInput = false)
|
||||
{
|
||||
instance.Execute(str, bufferInput);
|
||||
}
|
||||
|
||||
public static string GetVariable(string variableName)
|
||||
{
|
||||
return instance.GetVariable(variableName);
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleInstance : IDisposable
|
||||
{
|
||||
private readonly List<string> consoleBufferHistory = new List<string>();
|
||||
private readonly Dictionary<string, ConsoleCommand> consoleCommands = new Dictionary<string, ConsoleCommand>();
|
||||
|
||||
//private static List<string> consoleLines = new List<string>();
|
||||
private readonly List<ConsoleLine> consoleLines = new List<ConsoleLine>();
|
||||
|
||||
private readonly Dictionary<string, ConsoleVariable> consoleVariables =
|
||||
new Dictionary<string, ConsoleVariable>();
|
||||
|
||||
private readonly Stopwatch stopwatch = Stopwatch.StartNew();
|
||||
|
||||
// Echoes developer/debug text to Console
|
||||
private string debugLastLine = "";
|
||||
public Action OnClose;
|
||||
|
||||
public Action OnOpen;
|
||||
public Action<string> OnPrint;
|
||||
|
||||
public bool ShowExecutedLines = true;
|
||||
|
||||
internal ConsoleInstance()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsOpen { get; internal set; } = true;
|
||||
|
||||
public bool IsSafeToQuit => stopwatch.Elapsed.TotalSeconds > 0.1;
|
||||
|
||||
public int DebugVerbosity { get; set; } = 1;
|
||||
public string LinePrefix { get; internal set; } = "]";
|
||||
|
||||
public IReadOnlyCollection<ConsoleLine> Lines => consoleLines.AsReadOnly();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
// Initializes the Console system.
|
||||
internal void InitConsoleSubsystems()
|
||||
{
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
var assemblies = currentDomain.GetAssemblies();
|
||||
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
// Skip common assemblies
|
||||
string assemblyName = assembly.GetName().Name;
|
||||
if (assemblyName == "System" ||
|
||||
assemblyName.StartsWith("System.") ||
|
||||
assemblyName.StartsWith("Mono.") ||
|
||||
assemblyName == "mscorlib" ||
|
||||
assemblyName == "Newtonsoft.Json" ||
|
||||
assemblyName.StartsWith("FlaxEngine.") ||
|
||||
assemblyName.StartsWith("JetBrains.") ||
|
||||
assemblyName.StartsWith("Microsoft.") ||
|
||||
assemblyName.StartsWith("nunit."))
|
||||
continue;
|
||||
|
||||
foreach (Type type in assembly.GetTypes())
|
||||
{
|
||||
var cmdParsed = new Dictionary<string, ConsoleCommand>();
|
||||
var cmdMethods = new Dictionary<string, List<MethodInfo>>();
|
||||
MethodInfo cmdInitializer = null;
|
||||
|
||||
foreach (MethodInfo method in type.GetMethods())
|
||||
{
|
||||
if (!method.IsStatic)
|
||||
continue;
|
||||
|
||||
var attributes = Attribute.GetCustomAttributes(method);
|
||||
|
||||
foreach (Attribute attr in attributes)
|
||||
if (attr is ConsoleCommandAttribute cmdAttribute)
|
||||
{
|
||||
//Console.Print("found cmd '" + cmdAttribute.name + "' bound to field '" + method.Name + "'");
|
||||
|
||||
// Defer constructing the command until we have parsed all the methods for it in this assembly.
|
||||
|
||||
List<MethodInfo> methods;
|
||||
if (!cmdMethods.TryGetValue(cmdAttribute.name, out methods))
|
||||
{
|
||||
methods = new List<MethodInfo>();
|
||||
cmdMethods.Add(cmdAttribute.name, methods);
|
||||
}
|
||||
|
||||
methods.Add(method);
|
||||
|
||||
ConsoleCommand cmd = new ConsoleCommand(cmdAttribute.name, null);
|
||||
if (!cmdParsed.ContainsKey(cmdAttribute.name))
|
||||
cmdParsed.Add(cmdAttribute.name, cmd);
|
||||
foreach (string alias in cmdAttribute.aliases)
|
||||
{
|
||||
if (!cmdParsed.ContainsKey(alias))
|
||||
cmdParsed.Add(alias, cmd);
|
||||
|
||||
List<MethodInfo> aliasMethods;
|
||||
if (!cmdMethods.TryGetValue(alias, out aliasMethods))
|
||||
{
|
||||
aliasMethods = new List<MethodInfo>();
|
||||
cmdMethods.Add(alias, aliasMethods);
|
||||
}
|
||||
|
||||
aliasMethods.Add(method);
|
||||
}
|
||||
}
|
||||
else if (attr is ConsoleSubsystemInitializer)
|
||||
{
|
||||
cmdInitializer = method;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kv in cmdParsed)
|
||||
{
|
||||
var methods = cmdMethods[kv.Key];
|
||||
ConsoleCommand definition = kv.Value;
|
||||
|
||||
ConsoleCommand cmd = new ConsoleCommand(definition.name, methods.ToArray());
|
||||
consoleCommands.Add(kv.Key, cmd);
|
||||
}
|
||||
|
||||
foreach (FieldInfo field in type.GetFields())
|
||||
{
|
||||
if (!field.IsStatic)
|
||||
continue;
|
||||
|
||||
var attributes = Attribute.GetCustomAttributes(field);
|
||||
|
||||
foreach (Attribute attr in attributes)
|
||||
if (attr is ConsoleVariableAttribute cvarAttribute)
|
||||
{
|
||||
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
|
||||
consoleVariables.Add(cvarAttribute.name,
|
||||
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, field));
|
||||
foreach (string alias in cvarAttribute.aliases)
|
||||
consoleVariables.Add(alias,
|
||||
new ConsoleVariable(cvarAttribute.name,
|
||||
cvarAttribute.flags | ConsoleFlags.NoSerialize, field));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PropertyInfo prop in type.GetProperties())
|
||||
{
|
||||
MethodInfo getter = prop.GetGetMethod();
|
||||
MethodInfo setter = prop.GetSetMethod();
|
||||
if (getter == null || setter == null || !getter.IsStatic || !setter.IsStatic)
|
||||
continue;
|
||||
|
||||
var attributes = Attribute.GetCustomAttributes(prop);
|
||||
|
||||
foreach (Attribute attr in attributes)
|
||||
if (attr is ConsoleVariableAttribute cvarAttribute)
|
||||
{
|
||||
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
|
||||
consoleVariables.Add(cvarAttribute.name,
|
||||
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, getter, setter));
|
||||
foreach (string alias in cvarAttribute.aliases)
|
||||
consoleVariables.Add(alias,
|
||||
new ConsoleVariable(cvarAttribute.name,
|
||||
cvarAttribute.flags | ConsoleFlags.NoSerialize, getter, setter));
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdInitializer != null)
|
||||
{
|
||||
Console.PrintDebug(2, "Initializing " + type.Name);
|
||||
cmdInitializer.Invoke(null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetBufferHistory(int index)
|
||||
{
|
||||
if (consoleBufferHistory.Count == 0)
|
||||
return null;
|
||||
|
||||
if (index > consoleBufferHistory.Count - 1 || index < 0)
|
||||
return null;
|
||||
|
||||
return consoleBufferHistory[index];
|
||||
}
|
||||
|
||||
// Echoes text to Console
|
||||
public void Print(string text)
|
||||
{
|
||||
debugLastLine = text;
|
||||
|
||||
foreach (string line in text.Split('\n'))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Echoes warning text to Console
|
||||
public void PrintWarning(string text)
|
||||
{
|
||||
foreach (string line in text.Split('\n'))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Echoes error text to Console
|
||||
public void PrintError(string text)
|
||||
{
|
||||
foreach (string line in text.Split('\n'))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
Debugger.Break();
|
||||
else
|
||||
throw new Exception(text);
|
||||
}
|
||||
|
||||
public void PrintDebug(int verbosity, bool noRepeat, string text)
|
||||
{
|
||||
if (DebugVerbosity < verbosity)
|
||||
return;
|
||||
|
||||
if (noRepeat)
|
||||
if (debugLastLine.Length == text.Length && debugLastLine == text)
|
||||
return;
|
||||
|
||||
debugLastLine = text;
|
||||
|
||||
foreach (string line in text.Split('\n'))
|
||||
{
|
||||
ConsoleLine lineEntry = new ConsoleLine(line);
|
||||
consoleLines.Add(lineEntry);
|
||||
OnPrint?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
// Opens the Console
|
||||
public void Open()
|
||||
{
|
||||
if (IsOpen)
|
||||
return;
|
||||
|
||||
IsOpen = true;
|
||||
OnOpen?.Invoke();
|
||||
}
|
||||
|
||||
// Closes the Console
|
||||
public void Close()
|
||||
{
|
||||
if (!IsOpen)
|
||||
return;
|
||||
|
||||
IsOpen = false;
|
||||
OnClose?.Invoke();
|
||||
|
||||
stopwatch.Restart();
|
||||
}
|
||||
|
||||
// Clears the content of the Console
|
||||
public void Clear()
|
||||
{
|
||||
consoleLines.Clear();
|
||||
}
|
||||
|
||||
public void Execute(string str, bool bufferInput = false)
|
||||
{
|
||||
if (bufferInput)
|
||||
consoleBufferHistory.Insert(0, str);
|
||||
|
||||
str = str.Trim();
|
||||
|
||||
if (ShowExecutedLines)
|
||||
Console.Print(LinePrefix + str);
|
||||
|
||||
string[] strs = str.Split(' ');
|
||||
string execute = strs[0];
|
||||
string executeLower = execute.ToLowerInvariant();
|
||||
string value = strs.Length > 1 ? str.Substring(execute.Length + 1) : null;
|
||||
|
||||
//Console.PrintDebug("Executed '" + execute + "' with params: '" + value + "'");
|
||||
|
||||
if (consoleCommands.TryGetValue(executeLower, out ConsoleCommand cmd))
|
||||
{
|
||||
string[] values = strs.Skip(1).ToArray();
|
||||
if (values.Length > 0)
|
||||
cmd.Invoke(values);
|
||||
else
|
||||
cmd.Invoke();
|
||||
//Console.Print("Command bound to '" + execute + "' is '" + cmd.method.Name + "'");
|
||||
}
|
||||
else if (consoleVariables.TryGetValue(executeLower, out ConsoleVariable cvar))
|
||||
{
|
||||
if (value != null)
|
||||
cvar.SetValue(value);
|
||||
|
||||
Console.Print("'" + execute + "' is '" + cvar.GetValueString() + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Print("Unknown command '" + execute + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public string GetVariable(string variableName)
|
||||
{
|
||||
if (consoleVariables.TryGetValue(variableName, out ConsoleVariable cvar))
|
||||
{
|
||||
string value = cvar.GetValueString();
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public abstract class ConsoleBaseAttribute : Attribute
|
||||
{
|
||||
internal string name;
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public abstract class ConsoleBaseAttribute : Attribute
|
||||
{
|
||||
// Additional aliases for this command, these should only be used with user interaction.
|
||||
// Commands such as 'cvarlist' should not list these in order to avoid clutter.
|
||||
internal string[] aliases = new string[0];
|
||||
internal string name;
|
||||
|
||||
// Additional aliases for this command, these should only be used with user interaction.
|
||||
// Commands such as 'cvarlist' should not list these in order to avoid clutter.
|
||||
internal string[] aliases = new string[0];
|
||||
public ConsoleBaseAttribute(string name)
|
||||
{
|
||||
this.name = name.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public ConsoleFlags flags { get; private set; }
|
||||
public ConsoleBaseAttribute(params string[] names)
|
||||
{
|
||||
name = names[0].ToLowerInvariant();
|
||||
aliases = new List<string>(names).Skip(1).Select(x => x.ToLowerInvariant()).ToArray();
|
||||
}
|
||||
|
||||
public ConsoleBaseAttribute(string name)
|
||||
{
|
||||
this.name = name.ToLowerInvariant();
|
||||
}
|
||||
public ConsoleFlags flags { get; private set; }
|
||||
}
|
||||
|
||||
public ConsoleBaseAttribute(params string[] names)
|
||||
{
|
||||
this.name = names[0].ToLowerInvariant();
|
||||
aliases = new List<string>(names).Skip(1).Select(x => x.ToLowerInvariant()).ToArray();
|
||||
}
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ConsoleVariableAttribute : ConsoleBaseAttribute
|
||||
{
|
||||
public ConsoleVariableAttribute(string name) : base(name)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ConsoleVariableAttribute : ConsoleBaseAttribute
|
||||
{
|
||||
public ConsoleVariableAttribute(string name) : base(name)
|
||||
{
|
||||
}
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ConsoleCommandAttribute : ConsoleBaseAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a command to Console system.
|
||||
/// </summary>
|
||||
/// <param name="name">Name used for calling this command.</param>
|
||||
public ConsoleCommandAttribute(string name) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ConsoleCommandAttribute : ConsoleBaseAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a command to Console system.
|
||||
/// </summary>
|
||||
/// <param name="name">Name used for calling this command.</param>
|
||||
public ConsoleCommandAttribute(string name) : base(name)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers a command to Console system.
|
||||
/// </summary>
|
||||
/// <param name="names">
|
||||
/// Names used for calling this command. First name is the main name for this command, rest of the
|
||||
/// names are aliases.
|
||||
/// </param>
|
||||
public ConsoleCommandAttribute(params string[] names) : base(names)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a command to Console system.
|
||||
/// </summary>
|
||||
/// <param name="names">Names used for calling this command. First name is the main name for this command, rest of the names are aliases.</param>
|
||||
public ConsoleCommandAttribute(params string[] names) : base(names)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the subsystem, must be called first before registering console commands.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ConsoleSubsystemInitializer : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructor for the subsystem, must be called first before registering console commands.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ConsoleSubsystemInitializer : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
internal struct ConsoleCommand
|
||||
{
|
||||
public string name { get; private set; }
|
||||
internal struct ConsoleCommand
|
||||
{
|
||||
public string name { get; }
|
||||
|
||||
private MethodInfo[] methods;
|
||||
private readonly MethodInfo[] methods;
|
||||
|
||||
public ConsoleCommand(string name, MethodInfo[] method)
|
||||
{
|
||||
this.name = name;
|
||||
this.methods = method;
|
||||
}
|
||||
public ConsoleCommand(string name, MethodInfo[] method)
|
||||
{
|
||||
this.name = name;
|
||||
methods = method;
|
||||
}
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
foreach (var method in methods)
|
||||
{
|
||||
var methodParameters = method.GetParameters();
|
||||
if (methodParameters.Length != 0)
|
||||
continue;
|
||||
public void Invoke()
|
||||
{
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
var methodParameters = method.GetParameters();
|
||||
if (methodParameters.Length != 0)
|
||||
continue;
|
||||
|
||||
method.Invoke(null, null);
|
||||
return;
|
||||
}
|
||||
method.Invoke(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception("Unexpected number of parameters.");
|
||||
}
|
||||
throw new Exception("Unexpected number of parameters.");
|
||||
}
|
||||
|
||||
public void Invoke(string[] parameters)
|
||||
{
|
||||
MethodInfo match = null;
|
||||
foreach (var method in methods)
|
||||
{
|
||||
var methodParameters = method.GetParameters();
|
||||
if (methodParameters.Length == 1 && methodParameters[0].ParameterType == typeof(string[]))
|
||||
{
|
||||
match = method;
|
||||
continue;
|
||||
}
|
||||
else if (methodParameters.Length != parameters.Length)
|
||||
continue;
|
||||
public void Invoke(string[] parameters)
|
||||
{
|
||||
MethodInfo match = null;
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
var methodParameters = method.GetParameters();
|
||||
if (methodParameters.Length == 1 && methodParameters[0].ParameterType == typeof(string[]))
|
||||
{
|
||||
match = method;
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: try to parse string parameters to needed types first,
|
||||
// may require finding the exact match first instead of first matching one.
|
||||
for (int i = 0; i < methodParameters.Length; i++)
|
||||
//if (methodParameters[i].ParameterType != parameters[i].GetType())
|
||||
if (methodParameters[i].ParameterType != typeof(string))
|
||||
continue;
|
||||
if (methodParameters.Length != parameters.Length)
|
||||
continue;
|
||||
|
||||
if (match != null)
|
||||
{
|
||||
// Prefer exact number of parameters over string[] match
|
||||
if (methodParameters.Length != parameters.Length)
|
||||
continue;
|
||||
}
|
||||
// TODO: try to parse string parameters to needed types first,
|
||||
// may require finding the exact match first instead of first matching one.
|
||||
for (int i = 0; i < methodParameters.Length; i++)
|
||||
//if (methodParameters[i].ParameterType != parameters[i].GetType())
|
||||
if (methodParameters[i].ParameterType != typeof(string))
|
||||
continue;
|
||||
|
||||
match = method;
|
||||
}
|
||||
if (match != null)
|
||||
// Prefer exact number of parameters over string[] match
|
||||
if (methodParameters.Length != parameters.Length)
|
||||
continue;
|
||||
|
||||
if (match != null)
|
||||
{
|
||||
if (match.GetParameters().Length == 1 && match.GetParameters()[0].ParameterType == typeof(string[]))
|
||||
match.Invoke(null, new object[] {parameters});
|
||||
else
|
||||
match.Invoke(null, parameters);
|
||||
match = method;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if (match != null)
|
||||
{
|
||||
if (match.GetParameters().Length == 1 && match.GetParameters()[0].ParameterType == typeof(string[]))
|
||||
match.Invoke(null, new object[] { parameters });
|
||||
else
|
||||
match.Invoke(null, parameters);
|
||||
|
||||
throw new Exception("Unexpected number of parameters.");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception("Unexpected number of parameters.");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,173 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
public class ConsoleInputTextBox : ConsoleTextBoxBase
|
||||
{
|
||||
public override string TextPrefix
|
||||
{
|
||||
get => Console.LinePrefix;
|
||||
}
|
||||
public class ConsoleInputTextBox : ConsoleTextBoxBase
|
||||
{
|
||||
private readonly ConsoleContentTextBox contentBox;
|
||||
|
||||
private ConsoleContentTextBox contentBox;
|
||||
private int inputHistoryIndex = -1;
|
||||
|
||||
protected override Rectangle TextRectangle => new Rectangle(0, 0, Width, Height);
|
||||
protected override Rectangle TextClipRectangle => new Rectangle(0, 0, Width, Height);
|
||||
public ConsoleInputTextBox()
|
||||
{
|
||||
}
|
||||
|
||||
public ConsoleInputTextBox() : base()
|
||||
{
|
||||
}
|
||||
public ConsoleInputTextBox(ConsoleContentTextBox contentBox, float x, float y, float width, float height) :
|
||||
base(x, y, width, height)
|
||||
{
|
||||
this.contentBox = contentBox;
|
||||
IsMultiline = true; // Not really but behaves better than single-line box
|
||||
}
|
||||
|
||||
public ConsoleInputTextBox(ConsoleContentTextBox contentBox, float x, float y, float width, float height) :
|
||||
base(x, y, width, height)
|
||||
{
|
||||
this.contentBox = contentBox;
|
||||
IsMultiline = true; // Not really but behaves better than single-line box
|
||||
}
|
||||
public override string TextPrefix => Console.LinePrefix;
|
||||
|
||||
private bool IsConsoleKeyPressed(KeyboardKeys key = KeyboardKeys.None)
|
||||
{
|
||||
// Ignore any characters generated by the key which opens the console
|
||||
string inputTextLower = Input.InputText.ToLowerInvariant();
|
||||
protected override Rectangle TextRectangle => new Rectangle(0, 0, Width, Height);
|
||||
protected override Rectangle TextClipRectangle => new Rectangle(0, 0, Width, Height);
|
||||
|
||||
IEnumerable<ActionConfig> consoleKeyMappings;
|
||||
if (key == KeyboardKeys.None)
|
||||
consoleKeyMappings = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key != KeyboardKeys.None);
|
||||
else
|
||||
consoleKeyMappings = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key == key);
|
||||
foreach (var mapping in consoleKeyMappings)
|
||||
{
|
||||
if (inputTextLower.Length > 0)
|
||||
{
|
||||
if ((mapping.Key == KeyboardKeys.Backslash || mapping.Key == KeyboardKeys.BackQuote) &&
|
||||
(inputTextLower.Contains('ö') ||
|
||||
inputTextLower.Contains('æ') ||
|
||||
inputTextLower.Contains('ø')))
|
||||
{
|
||||
continue; // Scandinavian keyboard layouts
|
||||
}
|
||||
else if (mapping.Key == KeyboardKeys.BackQuote && inputTextLower.Contains('\''))
|
||||
continue;
|
||||
else if (mapping.Key == KeyboardKeys.Backslash &&
|
||||
(inputTextLower.Contains('\\') || inputTextLower.Contains('|')))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
private bool IsConsoleKeyPressed(KeyboardKeys key = KeyboardKeys.None)
|
||||
{
|
||||
// Ignore any characters generated by the key which opens the console
|
||||
string inputTextLower = Input.InputText.ToLowerInvariant();
|
||||
|
||||
if (Input.GetKey(mapping.Key))
|
||||
return true;
|
||||
}
|
||||
IEnumerable<ActionConfig> consoleKeyMappings;
|
||||
if (key == KeyboardKeys.None)
|
||||
consoleKeyMappings = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key != KeyboardKeys.None);
|
||||
else
|
||||
consoleKeyMappings = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key == key);
|
||||
foreach (ActionConfig mapping in consoleKeyMappings)
|
||||
{
|
||||
if (inputTextLower.Length > 0)
|
||||
{
|
||||
if ((mapping.Key == KeyboardKeys.Backslash || mapping.Key == KeyboardKeys.BackQuote) &&
|
||||
(inputTextLower.Contains('ö') ||
|
||||
inputTextLower.Contains('æ') ||
|
||||
inputTextLower.Contains('ø')))
|
||||
continue; // Scandinavian keyboard layouts
|
||||
if (mapping.Key == KeyboardKeys.BackQuote && inputTextLower.Contains('\''))
|
||||
continue;
|
||||
if (mapping.Key == KeyboardKeys.Backslash &&
|
||||
(inputTextLower.Contains('\\') || inputTextLower.Contains('|')))
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if (Input.GetKey(mapping.Key))
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnCharInput(char c)
|
||||
{
|
||||
if (IsConsoleKeyPressed())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnCharInput(c);
|
||||
}
|
||||
public override bool OnCharInput(char c)
|
||||
{
|
||||
if (IsConsoleKeyPressed())
|
||||
return true;
|
||||
|
||||
private int inputHistoryIndex = -1;
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
|
||||
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
|
||||
return base.OnCharInput(c);
|
||||
}
|
||||
|
||||
if (IsConsoleKeyPressed(key))
|
||||
{
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
else if (key == KeyboardKeys.Escape)
|
||||
{
|
||||
Console.Close();
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
else if (key == KeyboardKeys.Return)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.Execute(Text, true);
|
||||
inputHistoryIndex = -1;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
|
||||
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
|
||||
|
||||
contentBox.ScrollOffset = 0;
|
||||
return true;
|
||||
}
|
||||
else if (key == KeyboardKeys.ArrowUp)
|
||||
{
|
||||
inputHistoryIndex++;
|
||||
if (IsConsoleKeyPressed(key))
|
||||
{
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
string line = Console.GetBufferHistory(inputHistoryIndex);
|
||||
if (line == null)
|
||||
{
|
||||
inputHistoryIndex--;
|
||||
return true;
|
||||
}
|
||||
if (key == KeyboardKeys.Escape)
|
||||
{
|
||||
Console.Close();
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
SetText(line);
|
||||
SetSelection(TextLength);
|
||||
return true;
|
||||
}
|
||||
else if (key == KeyboardKeys.ArrowDown)
|
||||
{
|
||||
if (inputHistoryIndex > 0)
|
||||
inputHistoryIndex--;
|
||||
if (key == KeyboardKeys.Return)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.Execute(Text, true);
|
||||
inputHistoryIndex = -1;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
string line = Console.GetBufferHistory(inputHistoryIndex);
|
||||
if (line == null)
|
||||
return true;
|
||||
contentBox.ScrollOffset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
SetText(line);
|
||||
SetSelection(TextLength);
|
||||
return true;
|
||||
}
|
||||
else if (key == KeyboardKeys.PageUp || key == KeyboardKeys.PageDown)
|
||||
{
|
||||
return contentBox.OnKeyDown(key);
|
||||
}
|
||||
if (key == KeyboardKeys.ArrowUp)
|
||||
{
|
||||
inputHistoryIndex++;
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
string line = Console.GetBufferHistory(inputHistoryIndex);
|
||||
if (line == null)
|
||||
{
|
||||
inputHistoryIndex--;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnLostFocus()
|
||||
{
|
||||
// Avoids reseting the caret location
|
||||
var oldEditing = _isEditing;
|
||||
_isEditing = false;
|
||||
base.OnLostFocus();
|
||||
_isEditing = oldEditing;
|
||||
}
|
||||
SetText(line);
|
||||
SetSelection(TextLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMouseDown(Vector2 location, MouseButton button)
|
||||
{
|
||||
base.OnMouseDown(location, button);
|
||||
return true;
|
||||
}
|
||||
if (key == KeyboardKeys.ArrowDown)
|
||||
{
|
||||
if (inputHistoryIndex > 0)
|
||||
inputHistoryIndex--;
|
||||
|
||||
public override bool OnMouseWheel(Vector2 location, float delta)
|
||||
{
|
||||
return contentBox.OnMouseWheel(location, delta);
|
||||
}
|
||||
string line = Console.GetBufferHistory(inputHistoryIndex);
|
||||
if (line == null)
|
||||
return true;
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
Profiler.BeginEvent("ConsoleInputTextBoxDraw");
|
||||
base.Draw();
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
}
|
||||
SetText(line);
|
||||
SetSelection(TextLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == KeyboardKeys.PageUp || key == KeyboardKeys.PageDown)
|
||||
return contentBox.OnKeyDown(key);
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
|
||||
public override void OnLostFocus()
|
||||
{
|
||||
// Avoids reseting the caret location
|
||||
bool oldEditing = _isEditing;
|
||||
_isEditing = false;
|
||||
base.OnLostFocus();
|
||||
_isEditing = oldEditing;
|
||||
}
|
||||
|
||||
public override bool OnMouseDown(Vector2 location, MouseButton button)
|
||||
{
|
||||
base.OnMouseDown(location, button);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMouseWheel(Vector2 location, float delta)
|
||||
{
|
||||
return contentBox.OnMouseWheel(location, delta);
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
Profiler.BeginEvent("ConsoleInputTextBoxDraw");
|
||||
base.Draw();
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
#if FLAX_EDITOR
|
||||
using FlaxEditor;
|
||||
#endif
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class ConsolePlugin : GamePlugin
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Debug.Log("ConsolePlugin Initialize");
|
||||
public class ConsolePlugin : GamePlugin
|
||||
{
|
||||
public static PluginDescription DescriptionInternal = new PluginDescription
|
||||
{
|
||||
Author = "Ari Vuollet",
|
||||
Name = "Console",
|
||||
Description = "Quake-like console",
|
||||
Version = Version.Parse("0.1.0"),
|
||||
IsAlpha = true,
|
||||
Category = "Game"
|
||||
};
|
||||
|
||||
Console.Init();
|
||||
}
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Debug.Log("ConsolePlugin Initialize");
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
base.Deinitialize();
|
||||
Debug.Log("ConsolePlugin Deinitialize");
|
||||
}
|
||||
Console.Init();
|
||||
}
|
||||
|
||||
public static PluginDescription DescriptionInternal = new PluginDescription()
|
||||
{
|
||||
Author = "Ari Vuollet",
|
||||
Name = "Console",
|
||||
Description = "Quake-like console",
|
||||
Version = Version.Parse("0.1.0"),
|
||||
IsAlpha = true,
|
||||
Category = "Game",
|
||||
};
|
||||
}
|
||||
public override void Deinitialize()
|
||||
{
|
||||
base.Deinitialize();
|
||||
Debug.Log("ConsolePlugin Deinitialize");
|
||||
}
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
public class ConsoleEditorPlugin : EditorPlugin
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
Debug.Log("ConsoleEditorPlugin Initialize");
|
||||
Console.Init();
|
||||
}
|
||||
public class ConsoleEditorPlugin : EditorPlugin
|
||||
{
|
||||
public override PluginDescription Description => ConsolePlugin.DescriptionInternal;
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
Debug.Log("ConsoleEditorPlugin Deinitialize");
|
||||
}
|
||||
public override Type GamePluginType => typeof(ConsolePlugin);
|
||||
|
||||
public override PluginDescription Description => ConsolePlugin.DescriptionInternal;
|
||||
public override void Initialize()
|
||||
{
|
||||
Debug.Log("ConsoleEditorPlugin Initialize");
|
||||
Console.Init();
|
||||
}
|
||||
|
||||
public override Type GamePluginType => typeof(ConsolePlugin);
|
||||
}
|
||||
public override void Deinitialize()
|
||||
{
|
||||
Debug.Log("ConsoleEditorPlugin Deinitialize");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,151 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Assertions;
|
||||
using FlaxEngine.GUI;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
public class ConsoleScript : Script
|
||||
{
|
||||
[Limit(5, 720, 1)] public int ConsoleFontSize = 16;
|
||||
public class ConsoleScript : Script
|
||||
{
|
||||
public Color BackgroundColor;
|
||||
|
||||
[Limit(0.05f, 1.0f, 1)] public float ConsoleHeight = 0.65f;
|
||||
public Texture BackgroundTexture;
|
||||
private ConsoleContentTextBox consoleBox;
|
||||
|
||||
[Limit(0)] public int ConsoleNotifyLines = 3;
|
||||
public FontAsset ConsoleFont;
|
||||
[Limit(5, 720)] public int ConsoleFontSize = 16;
|
||||
|
||||
[Limit(0f)] public float ConsoleSpeed = 3500f;
|
||||
[Limit(0.05f, 1.0f)] public float ConsoleHeight = 0.65f;
|
||||
private ConsoleInputTextBox consoleInputBox;
|
||||
|
||||
public FontAsset ConsoleFont;
|
||||
internal InputEvent consoleInputEvent;
|
||||
private ConsoleContentTextBox consoleNotifyBox;
|
||||
|
||||
public Texture BackgroundTexture;
|
||||
[Limit(0)] public int ConsoleNotifyLines = 3;
|
||||
|
||||
public Color BackgroundColor;
|
||||
[Limit(0f)] public float ConsoleSpeed = 3500f;
|
||||
|
||||
private UIControl rootControl;
|
||||
private ConsoleContentTextBox consoleBox;
|
||||
private ConsoleInputTextBox consoleInputBox;
|
||||
private ConsoleContentTextBox consoleNotifyBox;
|
||||
private UIControl rootControl;
|
||||
|
||||
internal InputEvent consoleInputEvent;
|
||||
public override void OnStart()
|
||||
{
|
||||
consoleInputEvent = new InputEvent("Console");
|
||||
consoleInputEvent.Triggered += OnConsoleInputEvent;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
consoleInputEvent = new InputEvent("Console");
|
||||
consoleInputEvent.Triggered += OnConsoleInputEvent;
|
||||
FontReference fontReference = new FontReference(ConsoleFont, ConsoleFontSize);
|
||||
Font fontRaw = fontReference.GetFont();
|
||||
int fontHeight = (int)(fontRaw.Height / Platform.DpiScale);
|
||||
|
||||
FontReference fontReference = new FontReference(ConsoleFont, ConsoleFontSize);
|
||||
Font fontRaw = fontReference.GetFont();
|
||||
int fontHeight = (int) (fontRaw.Height / Platform.DpiScale);
|
||||
// root actor which holds all the elements
|
||||
//var rootContainerControl = new ContainerControl(new Rectangle(0, 0, screenSize.X, screenSize.Y));
|
||||
ContainerControl rootContainerControl = new ContainerControl(new Rectangle());
|
||||
rootContainerControl.SetAnchorPreset(AnchorPresets.StretchAll, false);
|
||||
|
||||
// root actor which holds all the elements
|
||||
//var rootContainerControl = new ContainerControl(new Rectangle(0, 0, screenSize.X, screenSize.Y));
|
||||
var rootContainerControl = new ContainerControl(new Rectangle());
|
||||
rootContainerControl.SetAnchorPreset(AnchorPresets.StretchAll, false);
|
||||
rootControl = Actor.AddChild<UIControl>();
|
||||
rootControl.Name = "ConsoleRoot";
|
||||
rootControl.Control = rootContainerControl;
|
||||
|
||||
rootControl = Actor.AddChild<UIControl>();
|
||||
rootControl.Name = "ConsoleRoot";
|
||||
rootControl.Control = rootContainerControl;
|
||||
VerticalPanel contentContainer = new VerticalPanel
|
||||
{
|
||||
AutoSize = true,
|
||||
Margin = Margin.Zero,
|
||||
Spacing = 0,
|
||||
Bounds = new Rectangle(),
|
||||
BackgroundColor = BackgroundColor
|
||||
};
|
||||
contentContainer.SetAnchorPreset(AnchorPresets.StretchAll, true);
|
||||
|
||||
var contentContainer = new VerticalPanel()
|
||||
{
|
||||
AutoSize = true,
|
||||
Margin = Margin.Zero,
|
||||
Spacing = 0,
|
||||
Bounds = new Rectangle(),
|
||||
BackgroundColor = BackgroundColor
|
||||
};
|
||||
contentContainer.SetAnchorPreset(AnchorPresets.StretchAll, true);
|
||||
UIControl contentContainerControl = rootControl.AddChild<UIControl>();
|
||||
contentContainerControl.Name = "ContentContainer";
|
||||
contentContainerControl.Control = contentContainer;
|
||||
|
||||
var contentContainerControl = rootControl.AddChild<UIControl>();
|
||||
contentContainerControl.Name = "ContentContainer";
|
||||
contentContainerControl.Control = contentContainer;
|
||||
|
||||
{
|
||||
if (consoleBox == null)
|
||||
{
|
||||
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
|
||||
consoleBox = new ConsoleContentTextBox(fontReference, null, 0, 0, 0, 0);
|
||||
{
|
||||
if (consoleBox == null)
|
||||
{
|
||||
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
|
||||
consoleBox = new ConsoleContentTextBox(fontReference, null, 0, 0, 0, 0);
|
||||
|
||||
|
||||
consoleBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
|
||||
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
|
||||
//consoleBox.Height = consoleSize.Y - fontHeight;
|
||||
consoleBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
|
||||
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
|
||||
//consoleBox.Height = consoleSize.Y - fontHeight;
|
||||
|
||||
//consoleBox.HorizontalAlignment = TextAlignment.Near;
|
||||
//consoleBox.VerticalAlignment = TextAlignment.Near;
|
||||
consoleBox.HeightMultiplier = ConsoleHeight;
|
||||
consoleBox.Wrapping = TextWrapping.WrapWords;
|
||||
consoleBox.BackgroundColor = Color.Transparent;
|
||||
consoleBox.BackgroundSelectedColor = Color.Transparent;
|
||||
consoleBox.BackgroundSelectedFlashSpeed = 0;
|
||||
consoleBox.BorderSelectedColor = Color.Transparent;
|
||||
consoleBox.CaretFlashSpeed = 0;
|
||||
}
|
||||
//consoleBox.HorizontalAlignment = TextAlignment.Near;
|
||||
//consoleBox.VerticalAlignment = TextAlignment.Near;
|
||||
consoleBox.HeightMultiplier = ConsoleHeight;
|
||||
consoleBox.Wrapping = TextWrapping.WrapWords;
|
||||
consoleBox.BackgroundColor = Color.Transparent;
|
||||
consoleBox.BackgroundSelectedColor = Color.Transparent;
|
||||
consoleBox.BackgroundSelectedFlashSpeed = 0;
|
||||
consoleBox.BorderSelectedColor = Color.Transparent;
|
||||
consoleBox.CaretFlashSpeed = 0;
|
||||
}
|
||||
|
||||
var locationFix = consoleBox.Location;
|
||||
var parentControl = contentContainerControl.AddChild<UIControl>();
|
||||
parentControl.Name = "ConsoleContent";
|
||||
parentControl.Control = consoleBox;
|
||||
consoleBox.Location = locationFix; // workaround to UIControl.Control overriding the old position
|
||||
Vector2 locationFix = consoleBox.Location;
|
||||
UIControl parentControl = contentContainerControl.AddChild<UIControl>();
|
||||
parentControl.Name = "ConsoleContent";
|
||||
parentControl.Control = consoleBox;
|
||||
consoleBox.Location = locationFix; // workaround to UIControl.Control overriding the old position
|
||||
|
||||
if (consoleNotifyBox == null)
|
||||
{
|
||||
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
|
||||
consoleNotifyBox = new ConsoleContentTextBox(fontReference, null, 0, 0, 0, 0);
|
||||
consoleNotifyBox.HeightMultiplier = 0;
|
||||
consoleNotifyBox.Height = ConsoleNotifyLines * fontHeight;
|
||||
consoleNotifyBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
|
||||
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
|
||||
if (consoleNotifyBox == null)
|
||||
{
|
||||
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
|
||||
consoleNotifyBox = new ConsoleContentTextBox(fontReference, null, 0, 0, 0, 0);
|
||||
consoleNotifyBox.HeightMultiplier = 0;
|
||||
consoleNotifyBox.Height = ConsoleNotifyLines * fontHeight;
|
||||
consoleNotifyBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
|
||||
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
|
||||
|
||||
//consoleBox.HorizontalAlignment = TextAlignment.Near;
|
||||
//consoleBox.VerticalAlignment = TextAlignment.Near;
|
||||
//consoleNotifyBox.HeightMultiplier = ConsoleHeight;
|
||||
consoleNotifyBox.Wrapping = TextWrapping.WrapWords;
|
||||
consoleNotifyBox.BackgroundColor = Color.Transparent;
|
||||
consoleNotifyBox.BackgroundSelectedColor = Color.Transparent;
|
||||
consoleNotifyBox.BackgroundSelectedFlashSpeed = 0;
|
||||
consoleNotifyBox.BorderSelectedColor = Color.Transparent;
|
||||
consoleNotifyBox.CaretFlashSpeed = 0;
|
||||
}
|
||||
//consoleBox.HorizontalAlignment = TextAlignment.Near;
|
||||
//consoleBox.VerticalAlignment = TextAlignment.Near;
|
||||
//consoleNotifyBox.HeightMultiplier = ConsoleHeight;
|
||||
consoleNotifyBox.Wrapping = TextWrapping.WrapWords;
|
||||
consoleNotifyBox.BackgroundColor = Color.Transparent;
|
||||
consoleNotifyBox.BackgroundSelectedColor = Color.Transparent;
|
||||
consoleNotifyBox.BackgroundSelectedFlashSpeed = 0;
|
||||
consoleNotifyBox.BorderSelectedColor = Color.Transparent;
|
||||
consoleNotifyBox.CaretFlashSpeed = 0;
|
||||
}
|
||||
|
||||
var locationFix2 = consoleNotifyBox.Location;
|
||||
var parentControl2 = Actor.AddChild<UIControl>();
|
||||
parentControl2.Name = "ConsoleNotifyContent";
|
||||
parentControl2.Control = consoleNotifyBox;
|
||||
consoleNotifyBox.Location = locationFix2; // workaround to UIControl.Control overriding the old position
|
||||
}
|
||||
{
|
||||
if (consoleInputBox == null)
|
||||
{
|
||||
//consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, consoleSize.Y - fontHeight, consoleSize.X, fontHeight);
|
||||
consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, 0, 0, 0);
|
||||
consoleInputBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false);
|
||||
//consoleInputBox.Location = new Vector2(0, consoleSize.Y - fontHeight);
|
||||
consoleInputBox.Height = fontHeight;
|
||||
Vector2 locationFix2 = consoleNotifyBox.Location;
|
||||
UIControl parentControl2 = Actor.AddChild<UIControl>();
|
||||
parentControl2.Name = "ConsoleNotifyContent";
|
||||
parentControl2.Control = consoleNotifyBox;
|
||||
consoleNotifyBox.Location = locationFix2; // workaround to UIControl.Control overriding the old position
|
||||
}
|
||||
{
|
||||
if (consoleInputBox == null)
|
||||
{
|
||||
//consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, consoleSize.Y - fontHeight, consoleSize.X, fontHeight);
|
||||
consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, 0, 0, 0);
|
||||
consoleInputBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false);
|
||||
//consoleInputBox.Location = new Vector2(0, consoleSize.Y - fontHeight);
|
||||
consoleInputBox.Height = fontHeight;
|
||||
|
||||
consoleInputBox.Font = fontReference;
|
||||
consoleBox.inputBox = consoleInputBox;
|
||||
consoleInputBox.Font = fontReference;
|
||||
consoleBox.inputBox = consoleInputBox;
|
||||
|
||||
consoleInputBox.Wrapping = TextWrapping.WrapWords;
|
||||
consoleInputBox.BackgroundColor = Color.Transparent;
|
||||
consoleInputBox.BackgroundSelectedColor = Color.Transparent;
|
||||
consoleInputBox.BackgroundSelectedFlashSpeed = 0;
|
||||
consoleInputBox.BorderSelectedColor = Color.Transparent;
|
||||
consoleInputBox.CaretFlashSpeed = 0;
|
||||
}
|
||||
consoleInputBox.Wrapping = TextWrapping.WrapWords;
|
||||
consoleInputBox.BackgroundColor = Color.Transparent;
|
||||
consoleInputBox.BackgroundSelectedColor = Color.Transparent;
|
||||
consoleInputBox.BackgroundSelectedFlashSpeed = 0;
|
||||
consoleInputBox.BorderSelectedColor = Color.Transparent;
|
||||
consoleInputBox.CaretFlashSpeed = 0;
|
||||
}
|
||||
|
||||
|
||||
Vector2 locationFix = consoleInputBox.Location;
|
||||
UIControl parentControl = contentContainerControl.AddChild<UIControl>();
|
||||
parentControl.Name = "ConsoleInput";
|
||||
parentControl.Control = consoleInputBox;
|
||||
|
||||
var locationFix = consoleInputBox.Location;
|
||||
var parentControl = contentContainerControl.AddChild<UIControl>();
|
||||
parentControl.Name = "ConsoleInput";
|
||||
parentControl.Control = consoleInputBox;
|
||||
|
||||
consoleInputBox.Location = locationFix; // workaround to UIControl.Control overriding the old position
|
||||
}
|
||||
consoleInputBox.Location = locationFix; // workaround to UIControl.Control overriding the old position
|
||||
}
|
||||
|
||||
#if false
|
||||
//for (int i = 0; i < 10; i++)
|
||||
@@ -208,191 +206,191 @@ namespace Cabrito
|
||||
Console.Print(l);
|
||||
}
|
||||
#endif
|
||||
/*FlaxEditor.Editor.Options.OptionsChanged += (FlaxEditor.Options.EditorOptions options) =>
|
||||
{
|
||||
/*FlaxEditor.Editor.Options.OptionsChanged += (FlaxEditor.Options.EditorOptions options) =>
|
||||
{
|
||||
|
||||
};*/
|
||||
};*/
|
||||
|
||||
/*Console.Print("normal line");
|
||||
Console.Print(
|
||||
"a very very very long long long line in repeat a very very very long long long line in repeat 1 a very very ver"
|
||||
+ "y long long long line in repeat a very very very 2 long long long line in repeat a very very very 3 long long"
|
||||
+ " long line in repeat a very very very long long long 4 line in repeat");
|
||||
Console.Print("another normal line");*/
|
||||
/*Console.Print("normal line");
|
||||
Console.Print(
|
||||
"a very very very long long long line in repeat a very very very long long long line in repeat 1 a very very ver"
|
||||
+ "y long long long line in repeat a very very very 2 long long long line in repeat a very very very 3 long long"
|
||||
+ " long line in repeat a very very very long long long 4 line in repeat");
|
||||
Console.Print("another normal line");*/
|
||||
|
||||
Debug.Logger.LogHandler.SendLog += OnSendLog;
|
||||
Debug.Logger.LogHandler.SendExceptionLog += OnSendExceptionLog;
|
||||
Debug.Logger.LogHandler.SendLog += OnSendLog;
|
||||
Debug.Logger.LogHandler.SendExceptionLog += OnSendExceptionLog;
|
||||
|
||||
Console.OnOpen += OnConsoleOpen;
|
||||
Console.OnClose += OnConsoleClose;
|
||||
Console.OnPrint += OnPrint;
|
||||
Console.OnOpen += OnConsoleOpen;
|
||||
Console.OnClose += OnConsoleClose;
|
||||
Console.OnPrint += OnPrint;
|
||||
|
||||
// hide console by default, and close it instantly
|
||||
Console.Close();
|
||||
var rootlocation = rootControl.Control.Location;
|
||||
rootlocation.Y = -rootControl.Control.Height;
|
||||
rootControl.Control.Location = rootlocation;
|
||||
// hide console by default, and close it instantly
|
||||
Console.Close();
|
||||
Vector2 rootlocation = rootControl.Control.Location;
|
||||
rootlocation.Y = -rootControl.Control.Height;
|
||||
rootControl.Control.Location = rootlocation;
|
||||
|
||||
Console.Print("Renderer: " + GPUDevice.Instance.RendererType);
|
||||
}
|
||||
Console.Print("Renderer: " + GPUDevice.Instance.RendererType);
|
||||
}
|
||||
|
||||
private void OnSendLog(LogType level, string msg, FlaxEngine.Object obj, string stackTrace)
|
||||
{
|
||||
Console.Print("[DEBUG] " + msg);
|
||||
}
|
||||
private void OnSendLog(LogType level, string msg, Object obj, string stackTrace)
|
||||
{
|
||||
Console.Print("[DEBUG] " + msg);
|
||||
}
|
||||
|
||||
private void OnSendExceptionLog(Exception exception, FlaxEngine.Object obj)
|
||||
{
|
||||
AssertionException assert = exception as AssertionException;
|
||||
if (assert != null)
|
||||
{
|
||||
var assertLines = assert.Message.Split('\n');
|
||||
if (assertLines.Length > 2)
|
||||
Console.Print("Assert Failure: " + assertLines[2]);
|
||||
else
|
||||
Console.Print("Assert Failure: " + assert.Message);
|
||||
}
|
||||
else
|
||||
Console.Print("[EXCEP] " + exception.Message);
|
||||
}
|
||||
private void OnSendExceptionLog(Exception exception, Object obj)
|
||||
{
|
||||
AssertionException assert = exception as AssertionException;
|
||||
if (assert != null)
|
||||
{
|
||||
string[] assertLines = assert.Message.Split('\n');
|
||||
if (assertLines.Length > 2)
|
||||
Console.Print("Assert Failure: " + assertLines[2]);
|
||||
else
|
||||
Console.Print("Assert Failure: " + assert.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Print("[EXCEP] " + exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
public override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
//consoleInputEvent.Triggered -= OnConsoleInputEvent;
|
||||
consoleInputEvent?.Dispose();
|
||||
consoleBox?.Dispose();
|
||||
consoleNotifyBox?.Dispose();
|
||||
//consoleInputEvent.Triggered -= OnConsoleInputEvent;
|
||||
consoleInputEvent?.Dispose();
|
||||
consoleBox?.Dispose();
|
||||
consoleNotifyBox?.Dispose();
|
||||
|
||||
Console.OnOpen -= OnConsoleOpen;
|
||||
Console.OnClose -= OnConsoleClose;
|
||||
Console.OnPrint -= OnPrint;
|
||||
Console.OnOpen -= OnConsoleOpen;
|
||||
Console.OnClose -= OnConsoleClose;
|
||||
Console.OnPrint -= OnPrint;
|
||||
|
||||
Debug.Logger.LogHandler.SendLog -= OnSendLog;
|
||||
Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog;
|
||||
}
|
||||
Debug.Logger.LogHandler.SendLog -= OnSendLog;
|
||||
Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog;
|
||||
}
|
||||
|
||||
private void OnConsoleInputEvent()
|
||||
{
|
||||
string currentInput = Input.InputText;
|
||||
private void OnConsoleInputEvent()
|
||||
{
|
||||
string currentInput = Input.InputText;
|
||||
|
||||
if (Input.InputText.Length > 0)
|
||||
{
|
||||
// Really need rawinput support with separate ActionConfig.RawKey values, bound to physical keys/scancode instead of virtual ones
|
||||
var consoleKeys = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key != KeyboardKeys.None);
|
||||
bool backslash = consoleKeys.Any(x => x.Key == KeyboardKeys.Backslash);
|
||||
bool backquote = consoleKeys.Any(x => x.Key == KeyboardKeys.BackQuote);
|
||||
if (Input.InputText.Length > 0)
|
||||
{
|
||||
// Really need rawinput support with separate ActionConfig.RawKey values, bound to physical keys/scancode instead of virtual ones
|
||||
var consoleKeys = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key != KeyboardKeys.None);
|
||||
bool backslash = consoleKeys.Any(x => x.Key == KeyboardKeys.Backslash);
|
||||
bool backquote = consoleKeys.Any(x => x.Key == KeyboardKeys.BackQuote);
|
||||
|
||||
// Workaround to only trigger Console key from key bound to left side of 1 (tilde/backquote/backslash key)
|
||||
if ((backslash || backquote) &&
|
||||
(Input.InputText.ToLowerInvariant().Contains('ö') ||
|
||||
Input.InputText.ToLowerInvariant().Contains('æ') ||
|
||||
Input.InputText.ToLowerInvariant().Contains('ø'))) // Scandinavian keyboard layouts
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (backquote && Input.InputText.ToLowerInvariant().Contains('\'')) // UK keyboard layouts
|
||||
return;
|
||||
else if (backslash && (Input.InputText.ToLowerInvariant().Contains('\\') ||
|
||||
Input.InputText.ToLowerInvariant()
|
||||
.Contains('|'))) // US/International keyboard layouts
|
||||
return;
|
||||
}
|
||||
// Workaround to only trigger Console key from key bound to left side of 1 (tilde/backquote/backslash key)
|
||||
if ((backslash || backquote) &&
|
||||
(Input.InputText.ToLowerInvariant().Contains('ö') ||
|
||||
Input.InputText.ToLowerInvariant().Contains('æ') ||
|
||||
Input.InputText.ToLowerInvariant().Contains('ø'))) // Scandinavian keyboard layouts
|
||||
return;
|
||||
if (backquote && Input.InputText.ToLowerInvariant().Contains('\'')) // UK keyboard layouts
|
||||
return;
|
||||
if (backslash && (Input.InputText.ToLowerInvariant().Contains('\\') ||
|
||||
Input.InputText.ToLowerInvariant()
|
||||
.Contains('|'))) // US/International keyboard layouts
|
||||
return;
|
||||
}
|
||||
|
||||
if (!consoleInputBox.IsFocused)
|
||||
Console.Open();
|
||||
else
|
||||
Console.Close();
|
||||
}
|
||||
if (!consoleInputBox.IsFocused)
|
||||
Console.Open();
|
||||
else
|
||||
Console.Close();
|
||||
}
|
||||
|
||||
public void OnConsoleOpen()
|
||||
{
|
||||
Screen.CursorVisible = true;
|
||||
Screen.CursorLock = CursorLockMode.None;
|
||||
public void OnConsoleOpen()
|
||||
{
|
||||
Screen.CursorVisible = true;
|
||||
Screen.CursorLock = CursorLockMode.None;
|
||||
|
||||
consoleInputBox.Focus();
|
||||
Parent.As<UICanvas>().ReceivesEvents = true;
|
||||
}
|
||||
consoleInputBox.Focus();
|
||||
Parent.As<UICanvas>().ReceivesEvents = true;
|
||||
}
|
||||
|
||||
public void OnConsoleClose()
|
||||
{
|
||||
Screen.CursorVisible = false;
|
||||
Screen.CursorLock = CursorLockMode.Locked;
|
||||
public void OnConsoleClose()
|
||||
{
|
||||
Screen.CursorVisible = false;
|
||||
Screen.CursorLock = CursorLockMode.Locked;
|
||||
|
||||
consoleInputBox.Defocus();
|
||||
consoleInputBox.Defocus();
|
||||
#if FLAX_EDITOR
|
||||
Editor.Instance.Windows.GameWin.Focus();
|
||||
Editor.Instance.Windows.GameWin.Focus();
|
||||
#endif
|
||||
Parent.As<UICanvas>().ReceivesEvents = false;
|
||||
}
|
||||
Parent.As<UICanvas>().ReceivesEvents = false;
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
base.OnUpdate();
|
||||
public override void OnUpdate()
|
||||
{
|
||||
base.OnUpdate();
|
||||
|
||||
if (!Console.IsOpen && Input.GetAction("ClearConsole"))
|
||||
Console.Clear();
|
||||
if (!Console.IsOpen && Input.GetAction("ClearConsole"))
|
||||
Console.Clear();
|
||||
|
||||
float targetY;
|
||||
float conHeight = rootControl.Control.Height /*/ Platform.DpiScale*/;
|
||||
if (!Console.IsOpen)
|
||||
targetY = -conHeight;
|
||||
else
|
||||
targetY = 0.0f;
|
||||
float targetY;
|
||||
float conHeight = rootControl.Control.Height /*/ Platform.DpiScale*/;
|
||||
if (!Console.IsOpen)
|
||||
targetY = -conHeight;
|
||||
else
|
||||
targetY = 0.0f;
|
||||
|
||||
Vector2 location = rootControl.Control.Location;
|
||||
if (location.Y != targetY)
|
||||
{
|
||||
if (location.Y > targetY)
|
||||
{
|
||||
// closing
|
||||
location.Y -= Time.UnscaledDeltaTime * ConsoleSpeed;
|
||||
if (location.Y < targetY)
|
||||
location.Y = targetY;
|
||||
Vector2 location = rootControl.Control.Location;
|
||||
if (location.Y != targetY)
|
||||
{
|
||||
if (location.Y > targetY)
|
||||
{
|
||||
// closing
|
||||
location.Y -= Time.UnscaledDeltaTime * ConsoleSpeed;
|
||||
if (location.Y < targetY)
|
||||
location.Y = targetY;
|
||||
|
||||
if (location.Y < targetY * ConsoleHeight)
|
||||
location.Y = targetY;
|
||||
}
|
||||
else if (location.Y < targetY)
|
||||
{
|
||||
// opening
|
||||
if (location.Y < -conHeight * ConsoleHeight)
|
||||
location.Y = -conHeight * ConsoleHeight;
|
||||
if (location.Y < targetY * ConsoleHeight)
|
||||
location.Y = targetY;
|
||||
}
|
||||
else if (location.Y < targetY)
|
||||
{
|
||||
// opening
|
||||
if (location.Y < -conHeight * ConsoleHeight)
|
||||
location.Y = -conHeight * ConsoleHeight;
|
||||
|
||||
location.Y += Time.UnscaledDeltaTime * ConsoleSpeed;
|
||||
if (location.Y > targetY)
|
||||
location.Y = targetY;
|
||||
}
|
||||
location.Y += Time.UnscaledDeltaTime * ConsoleSpeed;
|
||||
if (location.Y > targetY)
|
||||
location.Y = targetY;
|
||||
}
|
||||
|
||||
rootControl.Control.Location = location;
|
||||
rootControl.Control.Location = location;
|
||||
|
||||
if (Console.IsOpen)
|
||||
{
|
||||
consoleNotifyBox.Visible = false;
|
||||
consoleInputBox.Visible = true;
|
||||
}
|
||||
else if (!Console.IsOpen)
|
||||
{
|
||||
int fontHeight = (int) (consoleNotifyBox.FontHeight / Platform.DpiScale);
|
||||
if (location.Y < (-conHeight * ConsoleHeight) + fontHeight)
|
||||
{
|
||||
consoleNotifyBox.Visible = true;
|
||||
consoleInputBox.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Console.IsOpen)
|
||||
{
|
||||
consoleNotifyBox.Visible = false;
|
||||
consoleInputBox.Visible = true;
|
||||
}
|
||||
else if (!Console.IsOpen)
|
||||
{
|
||||
int fontHeight = (int)(consoleNotifyBox.FontHeight / Platform.DpiScale);
|
||||
if (location.Y < -conHeight * ConsoleHeight + fontHeight)
|
||||
{
|
||||
consoleNotifyBox.Visible = true;
|
||||
consoleInputBox.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPrint(string text)
|
||||
{
|
||||
int fontHeight = (int) (consoleNotifyBox.FontHeight / Platform.DpiScale);
|
||||
consoleNotifyBox.Height = Math.Min(ConsoleNotifyLines, Console.Lines.Count) * fontHeight;
|
||||
}
|
||||
public void OnPrint(string text)
|
||||
{
|
||||
int fontHeight = (int)(consoleNotifyBox.FontHeight / Platform.DpiScale);
|
||||
consoleNotifyBox.Height = Math.Min(ConsoleNotifyLines, Console.Lines.Count) * fontHeight;
|
||||
}
|
||||
|
||||
public void SetInput(string text)
|
||||
{
|
||||
consoleInputBox.Text = text;
|
||||
}
|
||||
}
|
||||
public void SetInput(string text)
|
||||
{
|
||||
consoleInputBox.Text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,390 +1,389 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor;
|
||||
using System.Diagnostics;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
// Mostly based on TextBox
|
||||
public class ConsoleTextBoxBase : TextBoxBase
|
||||
{
|
||||
protected TextLayoutOptions _layout;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text wrapping within the control bounds.
|
||||
/// </summary>
|
||||
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The text wrapping within the control bounds.")]
|
||||
public TextWrapping Wrapping
|
||||
{
|
||||
get => _layout.TextWrapping;
|
||||
set => _layout.TextWrapping = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the font.
|
||||
/// </summary>
|
||||
[EditorDisplay("Style"), EditorOrder(2000)]
|
||||
public FontReference Font { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the text.
|
||||
/// </summary>
|
||||
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the text.")]
|
||||
public Color TextColor = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the selection (Transparent if not used).
|
||||
/// </summary>
|
||||
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the selection (Transparent if not used).")]
|
||||
public Color SelectionColor = new Color(0x00, 0x7A, 0xCC, 0xFF);
|
||||
|
||||
[HideInEditor] public virtual string TextPrefix { get; set; } = "";
|
||||
|
||||
//[HideInEditor]
|
||||
//public override string Text => _text;
|
||||
|
||||
public ConsoleTextBoxBase() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public ConsoleTextBoxBase(float x, float y, float width, float height) : base(false, x, y, width)
|
||||
{
|
||||
Height = height;
|
||||
|
||||
IsReadOnly = false;
|
||||
CaretColor = new Color(1f, 1f, 1f, 1f);
|
||||
AutoFocus = true;
|
||||
|
||||
_layout = TextLayoutOptions.Default;
|
||||
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
|
||||
_layout.TextWrapping = TextWrapping.NoWrap;
|
||||
_layout.Bounds =
|
||||
new Rectangle(0, 0, Width,
|
||||
Height); //new Rectangle(DefaultMargin, 1, Width - 2 * DefaultMargin, Height - 2);
|
||||
}
|
||||
|
||||
/*protected override void SetText(string value)
|
||||
{
|
||||
// Prevent from null problems
|
||||
if (value == null)
|
||||
value = string.Empty;
|
||||
|
||||
// Filter text
|
||||
if (value.IndexOf('\r') != -1)
|
||||
value = value.Replace("\r", "");
|
||||
|
||||
// Clamp length
|
||||
if (value.Length > MaxLength)
|
||||
value = value.Substring(0, MaxLength);
|
||||
|
||||
// Ensure to use only single line
|
||||
if (_isMultiline == false && value.Length > 0)
|
||||
{
|
||||
// Extract only the first line
|
||||
value = value.GetLines()[0];
|
||||
}
|
||||
|
||||
if (Text != value)
|
||||
{
|
||||
Deselect();
|
||||
ResetViewOffset();
|
||||
|
||||
Text = value;
|
||||
|
||||
OnTextChanged();
|
||||
}
|
||||
}*/
|
||||
|
||||
public int GetFontHeight()
|
||||
{
|
||||
var font = Font.GetFont();
|
||||
if (font == null)
|
||||
return (int) Height;
|
||||
|
||||
return (int) Mathf.Round(font.Height * Scale.Y);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
// Can't clear the text while user is editing it...
|
||||
var oldEditing = _isEditing;
|
||||
_isEditing = false;
|
||||
base.Clear();
|
||||
_isEditing = oldEditing;
|
||||
}
|
||||
|
||||
public override void ResetViewOffset()
|
||||
{
|
||||
TargetViewOffset = new Vector2(0, 0);
|
||||
}
|
||||
|
||||
/*public void ScrollToEnd()
|
||||
{
|
||||
float maxY = TextSize.Y - Height;
|
||||
float spacing = GetRealLineSpacing();
|
||||
maxY += spacing;
|
||||
|
||||
TargetViewOffset = new Vector2(0, Math.Max(0, maxY));
|
||||
}*/
|
||||
|
||||
public override void ScrollToCaret()
|
||||
{
|
||||
if (Text.Length == 0)
|
||||
return;
|
||||
|
||||
Rectangle caretBounds = CaretBounds;
|
||||
|
||||
float maxY = TextSize.Y - Height;
|
||||
|
||||
Vector2 newLocation = CaretBounds.Location;
|
||||
TargetViewOffset = Vector2.Clamp(newLocation, new Vector2(0, 0), new Vector2(_targetViewOffset.X, maxY));
|
||||
}
|
||||
|
||||
/*const bool smoothScrolling = false;
|
||||
|
||||
public override bool OnMouseWheel(Vector2 location, float delta)
|
||||
{
|
||||
if (!IsMultiline || Text.Length == 0)
|
||||
return false;
|
||||
|
||||
if (!smoothScrolling)
|
||||
delta = GetFontHeight() * Math.Sign(delta) * 3;
|
||||
else
|
||||
delta *= 30;
|
||||
|
||||
float maxY = TextSize.Y - Height;
|
||||
float offset = GetRealLineSpacing();
|
||||
maxY += offset;
|
||||
TargetViewOffset = Vector2.Clamp(_targetViewOffset - new Vector2(0, delta), new Vector2(0, offset), new Vector2(_targetViewOffset.X, maxY));
|
||||
return true;
|
||||
}*/
|
||||
|
||||
public override Vector2 GetTextSize()
|
||||
{
|
||||
var font = Font.GetFont();
|
||||
if (font == null)
|
||||
return Vector2.Zero;
|
||||
|
||||
return font.MeasureText(Text, ref _layout);
|
||||
}
|
||||
|
||||
public override Vector2 GetCharPosition(int index, out float height)
|
||||
{
|
||||
var font = Font.GetFont();
|
||||
if (font == null)
|
||||
{
|
||||
height = Height;
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
height = GetFontHeight();
|
||||
return font.GetCharPosition(Text, index, ref _layout);
|
||||
}
|
||||
|
||||
public override int HitTestText(Vector2 location)
|
||||
{
|
||||
var font = Font.GetFont();
|
||||
if (font == null)
|
||||
return 0;
|
||||
|
||||
if (TextPrefix != "")
|
||||
{
|
||||
var prefixSize = font.MeasureText(TextPrefix);
|
||||
location.X -= prefixSize.X;
|
||||
}
|
||||
|
||||
return font.HitTestText(Text, location, ref _layout);
|
||||
}
|
||||
|
||||
protected override void OnIsMultilineChanged()
|
||||
{
|
||||
base.OnIsMultilineChanged();
|
||||
|
||||
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
|
||||
}
|
||||
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
|
||||
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
|
||||
|
||||
if (shiftDown && key == KeyboardKeys.Delete)
|
||||
Cut();
|
||||
else if (ctrlDown && key == KeyboardKeys.Insert)
|
||||
Copy();
|
||||
else if (shiftDown && key == KeyboardKeys.Insert)
|
||||
Paste();
|
||||
if (shiftDown && key == KeyboardKeys.Home)
|
||||
{
|
||||
if (!IsReadOnly)
|
||||
SetSelection(_selectionStart, 0);
|
||||
return true;
|
||||
}
|
||||
else if (shiftDown && key == KeyboardKeys.End)
|
||||
{
|
||||
if (!IsReadOnly)
|
||||
SetSelection(_selectionStart, TextLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
|
||||
bool doubleClicked = false;
|
||||
System.Diagnostics.Stopwatch lastDoubleClick = new System.Diagnostics.Stopwatch();
|
||||
Vector2 lastDoubleClickLocation = new Vector2(0, 0);
|
||||
|
||||
public override bool OnMouseDown(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (doubleClicked && lastDoubleClick.Elapsed.TotalSeconds < 0.5 &&
|
||||
location == lastDoubleClickLocation) // Windows defaults to 500ms window
|
||||
{
|
||||
doubleClicked = false;
|
||||
if (OnMouseTripleClick(location, button))
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
|
||||
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
|
||||
{
|
||||
doubleClicked = true;
|
||||
lastDoubleClick.Restart();
|
||||
lastDoubleClickLocation = location;
|
||||
|
||||
return base.OnMouseDoubleClick(location, button);
|
||||
}
|
||||
|
||||
public bool OnMouseTripleClick(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (!IsMultiline)
|
||||
SelectAll();
|
||||
else
|
||||
{
|
||||
// TODO: select the line
|
||||
SelectAll();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged()
|
||||
{
|
||||
base.OnSizeChanged();
|
||||
|
||||
_layout.Bounds = TextRectangle;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
// Cache data
|
||||
var rect = new Rectangle(Vector2.Zero, Size);
|
||||
var font = Font.GetFont();
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
// Background
|
||||
Color backColor = BackgroundColor;
|
||||
if (IsMouseOver)
|
||||
backColor = BackgroundSelectedColor;
|
||||
if (backColor.A > 0.0f)
|
||||
Render2D.FillRectangle(rect, backColor);
|
||||
|
||||
Color borderColor = IsFocused ? BorderSelectedColor : BorderColor;
|
||||
if (borderColor.A > 0.0f)
|
||||
Render2D.DrawRectangle(rect, borderColor);
|
||||
|
||||
//string text = TextPrefix + Text;
|
||||
string text = TextPrefix + Text;
|
||||
|
||||
if (text.Length == 0)
|
||||
return;
|
||||
|
||||
// Apply view offset and clip mask
|
||||
Render2D.PushClip(TextClipRectangle);
|
||||
bool useViewOffset = !_viewOffset.IsZero;
|
||||
if (useViewOffset)
|
||||
Render2D.PushTransform(Matrix3x3.Translation2D(-_viewOffset));
|
||||
|
||||
// Check if any text is selected to draw selection
|
||||
if (HasSelection)
|
||||
{
|
||||
Vector2 leftEdge = font.GetCharPosition(text, SelectionLeft + TextPrefix.Length, ref _layout);
|
||||
Vector2 rightEdge = font.GetCharPosition(text, SelectionRight + TextPrefix.Length, ref _layout);
|
||||
float fontHeight = GetFontHeight();
|
||||
|
||||
// Draw selection background
|
||||
float alpha = Mathf.Min(1.0f, Mathf.Cos(_animateTime * BackgroundSelectedFlashSpeed) * 0.5f + 1.3f);
|
||||
alpha = alpha * alpha;
|
||||
Color selectionColor = SelectionColor * alpha;
|
||||
|
||||
int selectedLinesCount = 1 + Mathf.FloorToInt((rightEdge.Y - leftEdge.Y) / fontHeight);
|
||||
if (selectedLinesCount == 1) // Selected is part of single line
|
||||
{
|
||||
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, rightEdge.X - leftEdge.X, fontHeight);
|
||||
Render2D.FillRectangle(r1, selectionColor);
|
||||
}
|
||||
else // Selected is more than one line
|
||||
{
|
||||
float leftMargin = _layout.Bounds.Location.X;
|
||||
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, 1000000000, fontHeight);
|
||||
Render2D.FillRectangle(r1, selectionColor);
|
||||
|
||||
for (int i = 3; i <= selectedLinesCount; i++)
|
||||
{
|
||||
leftEdge.Y += fontHeight;
|
||||
Rectangle r = new Rectangle(leftMargin, leftEdge.Y, 1000000000, fontHeight);
|
||||
Render2D.FillRectangle(r, selectionColor);
|
||||
}
|
||||
|
||||
Rectangle r2 = new Rectangle(leftMargin, rightEdge.Y, rightEdge.X - leftMargin, fontHeight);
|
||||
Render2D.FillRectangle(r2, selectionColor);
|
||||
}
|
||||
}
|
||||
|
||||
Render2D.DrawText(font, text, TextColor, ref _layout);
|
||||
|
||||
if (CaretPosition > -1)
|
||||
{
|
||||
var prefixSize = TextPrefix != "" ? font.MeasureText(TextPrefix) : new Vector2();
|
||||
var caretBounds = CaretBounds;
|
||||
caretBounds.X += prefixSize.X;
|
||||
|
||||
float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.7f);
|
||||
alpha = alpha * alpha * alpha * alpha * alpha * alpha;
|
||||
Render2D.FillRectangle(caretBounds, CaretColor * alpha);
|
||||
}
|
||||
|
||||
// Restore rendering state
|
||||
if (useViewOffset)
|
||||
Render2D.PopTransform();
|
||||
Render2D.PopClip();
|
||||
}
|
||||
|
||||
public override void Paste()
|
||||
{
|
||||
if (IsReadOnly)
|
||||
return;
|
||||
|
||||
var clipboardText = Clipboard.Text;
|
||||
// Handle newlines in clipboard text
|
||||
if (!string.IsNullOrEmpty(clipboardText))
|
||||
{
|
||||
// TODO: probably better to just split these lines and parse each line separately
|
||||
clipboardText = clipboardText.Replace("\r\n", "");
|
||||
clipboardText = clipboardText.Replace("\n", "");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(clipboardText))
|
||||
{
|
||||
var right = SelectionRight;
|
||||
Insert(clipboardText);
|
||||
SetSelection(Mathf.Max(right, 0) + clipboardText.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Mostly based on TextBox
|
||||
public class ConsoleTextBoxBase : TextBoxBase
|
||||
{
|
||||
private readonly Stopwatch lastDoubleClick = new Stopwatch();
|
||||
protected TextLayoutOptions _layout;
|
||||
|
||||
private bool doubleClicked;
|
||||
private Vector2 lastDoubleClickLocation = new Vector2(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the selection (Transparent if not used).
|
||||
/// </summary>
|
||||
[EditorDisplay("Style")] [EditorOrder(2000)] [Tooltip("The color of the selection (Transparent if not used).")]
|
||||
public Color SelectionColor = new Color(0x00, 0x7A, 0xCC);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the text.
|
||||
/// </summary>
|
||||
[EditorDisplay("Style")] [EditorOrder(2000)] [Tooltip("The color of the text.")]
|
||||
public Color TextColor = Color.White;
|
||||
|
||||
//[HideInEditor]
|
||||
//public override string Text => _text;
|
||||
|
||||
public ConsoleTextBoxBase()
|
||||
{
|
||||
}
|
||||
|
||||
public ConsoleTextBoxBase(float x, float y, float width, float height) : base(false, x, y, width)
|
||||
{
|
||||
Height = height;
|
||||
|
||||
IsReadOnly = false;
|
||||
CaretColor = new Color(1f, 1f, 1f, 1f);
|
||||
AutoFocus = true;
|
||||
|
||||
_layout = TextLayoutOptions.Default;
|
||||
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
|
||||
_layout.TextWrapping = TextWrapping.NoWrap;
|
||||
_layout.Bounds =
|
||||
new Rectangle(0, 0, Width,
|
||||
Height); //new Rectangle(DefaultMargin, 1, Width - 2 * DefaultMargin, Height - 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text wrapping within the control bounds.
|
||||
/// </summary>
|
||||
[EditorDisplay("Style")]
|
||||
[EditorOrder(2000)]
|
||||
[Tooltip("The text wrapping within the control bounds.")]
|
||||
public TextWrapping Wrapping
|
||||
{
|
||||
get => _layout.TextWrapping;
|
||||
set => _layout.TextWrapping = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the font.
|
||||
/// </summary>
|
||||
[EditorDisplay("Style")]
|
||||
[EditorOrder(2000)]
|
||||
public FontReference Font { get; set; }
|
||||
|
||||
[HideInEditor] public virtual string TextPrefix { get; set; } = "";
|
||||
|
||||
/*protected override void SetText(string value)
|
||||
{
|
||||
// Prevent from null problems
|
||||
if (value == null)
|
||||
value = string.Empty;
|
||||
|
||||
// Filter text
|
||||
if (value.IndexOf('\r') != -1)
|
||||
value = value.Replace("\r", "");
|
||||
|
||||
// Clamp length
|
||||
if (value.Length > MaxLength)
|
||||
value = value.Substring(0, MaxLength);
|
||||
|
||||
// Ensure to use only single line
|
||||
if (_isMultiline == false && value.Length > 0)
|
||||
{
|
||||
// Extract only the first line
|
||||
value = value.GetLines()[0];
|
||||
}
|
||||
|
||||
if (Text != value)
|
||||
{
|
||||
Deselect();
|
||||
ResetViewOffset();
|
||||
|
||||
Text = value;
|
||||
|
||||
OnTextChanged();
|
||||
}
|
||||
}*/
|
||||
|
||||
public int GetFontHeight()
|
||||
{
|
||||
Font font = Font.GetFont();
|
||||
if (font == null)
|
||||
return (int)Height;
|
||||
|
||||
return (int)Mathf.Round(font.Height * Scale.Y);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
// Can't clear the text while user is editing it...
|
||||
bool oldEditing = _isEditing;
|
||||
_isEditing = false;
|
||||
base.Clear();
|
||||
_isEditing = oldEditing;
|
||||
}
|
||||
|
||||
public override void ResetViewOffset()
|
||||
{
|
||||
TargetViewOffset = new Vector2(0, 0);
|
||||
}
|
||||
|
||||
/*public void ScrollToEnd()
|
||||
{
|
||||
float maxY = TextSize.Y - Height;
|
||||
float spacing = GetRealLineSpacing();
|
||||
maxY += spacing;
|
||||
|
||||
TargetViewOffset = new Vector2(0, Math.Max(0, maxY));
|
||||
}*/
|
||||
|
||||
public override void ScrollToCaret()
|
||||
{
|
||||
if (Text.Length == 0)
|
||||
return;
|
||||
|
||||
Rectangle caretBounds = CaretBounds;
|
||||
|
||||
float maxY = TextSize.Y - Height;
|
||||
|
||||
Vector2 newLocation = CaretBounds.Location;
|
||||
TargetViewOffset = Vector2.Clamp(newLocation, new Vector2(0, 0), new Vector2(_targetViewOffset.X, maxY));
|
||||
}
|
||||
|
||||
/*const bool smoothScrolling = false;
|
||||
|
||||
public override bool OnMouseWheel(Vector2 location, float delta)
|
||||
{
|
||||
if (!IsMultiline || Text.Length == 0)
|
||||
return false;
|
||||
|
||||
if (!smoothScrolling)
|
||||
delta = GetFontHeight() * Math.Sign(delta) * 3;
|
||||
else
|
||||
delta *= 30;
|
||||
|
||||
float maxY = TextSize.Y - Height;
|
||||
float offset = GetRealLineSpacing();
|
||||
maxY += offset;
|
||||
TargetViewOffset = Vector2.Clamp(_targetViewOffset - new Vector2(0, delta), new Vector2(0, offset), new Vector2(_targetViewOffset.X, maxY));
|
||||
return true;
|
||||
}*/
|
||||
|
||||
public override Vector2 GetTextSize()
|
||||
{
|
||||
Font font = Font.GetFont();
|
||||
if (font == null)
|
||||
return Vector2.Zero;
|
||||
|
||||
return font.MeasureText(Text, ref _layout);
|
||||
}
|
||||
|
||||
public override Vector2 GetCharPosition(int index, out float height)
|
||||
{
|
||||
Font font = Font.GetFont();
|
||||
if (font == null)
|
||||
{
|
||||
height = Height;
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
height = GetFontHeight();
|
||||
return font.GetCharPosition(Text, index, ref _layout);
|
||||
}
|
||||
|
||||
public override int HitTestText(Vector2 location)
|
||||
{
|
||||
Font font = Font.GetFont();
|
||||
if (font == null)
|
||||
return 0;
|
||||
|
||||
if (TextPrefix != "")
|
||||
{
|
||||
Vector2 prefixSize = font.MeasureText(TextPrefix);
|
||||
location.X -= prefixSize.X;
|
||||
}
|
||||
|
||||
return font.HitTestText(Text, location, ref _layout);
|
||||
}
|
||||
|
||||
protected override void OnIsMultilineChanged()
|
||||
{
|
||||
base.OnIsMultilineChanged();
|
||||
|
||||
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
|
||||
}
|
||||
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
|
||||
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
|
||||
|
||||
if (shiftDown && key == KeyboardKeys.Delete)
|
||||
Cut();
|
||||
else if (ctrlDown && key == KeyboardKeys.Insert)
|
||||
Copy();
|
||||
else if (shiftDown && key == KeyboardKeys.Insert)
|
||||
Paste();
|
||||
if (shiftDown && key == KeyboardKeys.Home)
|
||||
{
|
||||
if (!IsReadOnly)
|
||||
SetSelection(_selectionStart, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shiftDown && key == KeyboardKeys.End)
|
||||
{
|
||||
if (!IsReadOnly)
|
||||
SetSelection(_selectionStart, TextLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
|
||||
public override bool OnMouseDown(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (doubleClicked && lastDoubleClick.Elapsed.TotalSeconds < 0.5 &&
|
||||
location == lastDoubleClickLocation) // Windows defaults to 500ms window
|
||||
{
|
||||
doubleClicked = false;
|
||||
if (OnMouseTripleClick(location, button))
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
|
||||
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
|
||||
{
|
||||
doubleClicked = true;
|
||||
lastDoubleClick.Restart();
|
||||
lastDoubleClickLocation = location;
|
||||
|
||||
return base.OnMouseDoubleClick(location, button);
|
||||
}
|
||||
|
||||
public bool OnMouseTripleClick(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (!IsMultiline)
|
||||
SelectAll();
|
||||
else
|
||||
// TODO: select the line
|
||||
SelectAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged()
|
||||
{
|
||||
base.OnSizeChanged();
|
||||
|
||||
_layout.Bounds = TextRectangle;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
// Cache data
|
||||
Rectangle rect = new Rectangle(Vector2.Zero, Size);
|
||||
Font font = Font.GetFont();
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
// Background
|
||||
Color backColor = BackgroundColor;
|
||||
if (IsMouseOver)
|
||||
backColor = BackgroundSelectedColor;
|
||||
if (backColor.A > 0.0f)
|
||||
Render2D.FillRectangle(rect, backColor);
|
||||
|
||||
Color borderColor = IsFocused ? BorderSelectedColor : BorderColor;
|
||||
if (borderColor.A > 0.0f)
|
||||
Render2D.DrawRectangle(rect, borderColor);
|
||||
|
||||
//string text = TextPrefix + Text;
|
||||
string text = TextPrefix + Text;
|
||||
|
||||
if (text.Length == 0)
|
||||
return;
|
||||
|
||||
// Apply view offset and clip mask
|
||||
Render2D.PushClip(TextClipRectangle);
|
||||
bool useViewOffset = !_viewOffset.IsZero;
|
||||
if (useViewOffset)
|
||||
Render2D.PushTransform(Matrix3x3.Translation2D(-_viewOffset));
|
||||
|
||||
// Check if any text is selected to draw selection
|
||||
if (HasSelection)
|
||||
{
|
||||
Vector2 leftEdge = font.GetCharPosition(text, SelectionLeft + TextPrefix.Length, ref _layout);
|
||||
Vector2 rightEdge = font.GetCharPosition(text, SelectionRight + TextPrefix.Length, ref _layout);
|
||||
float fontHeight = GetFontHeight();
|
||||
|
||||
// Draw selection background
|
||||
float alpha = Mathf.Min(1.0f, Mathf.Cos(_animateTime * BackgroundSelectedFlashSpeed) * 0.5f + 1.3f);
|
||||
alpha = alpha * alpha;
|
||||
Color selectionColor = SelectionColor * alpha;
|
||||
|
||||
int selectedLinesCount = 1 + Mathf.FloorToInt((rightEdge.Y - leftEdge.Y) / fontHeight);
|
||||
if (selectedLinesCount == 1) // Selected is part of single line
|
||||
{
|
||||
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, rightEdge.X - leftEdge.X, fontHeight);
|
||||
Render2D.FillRectangle(r1, selectionColor);
|
||||
}
|
||||
else // Selected is more than one line
|
||||
{
|
||||
float leftMargin = _layout.Bounds.Location.X;
|
||||
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, 1000000000, fontHeight);
|
||||
Render2D.FillRectangle(r1, selectionColor);
|
||||
|
||||
for (int i = 3; i <= selectedLinesCount; i++)
|
||||
{
|
||||
leftEdge.Y += fontHeight;
|
||||
Rectangle r = new Rectangle(leftMargin, leftEdge.Y, 1000000000, fontHeight);
|
||||
Render2D.FillRectangle(r, selectionColor);
|
||||
}
|
||||
|
||||
Rectangle r2 = new Rectangle(leftMargin, rightEdge.Y, rightEdge.X - leftMargin, fontHeight);
|
||||
Render2D.FillRectangle(r2, selectionColor);
|
||||
}
|
||||
}
|
||||
|
||||
Render2D.DrawText(font, text, TextColor, ref _layout);
|
||||
|
||||
if (CaretPosition > -1)
|
||||
{
|
||||
Vector2 prefixSize = TextPrefix != "" ? font.MeasureText(TextPrefix) : new Vector2();
|
||||
Rectangle caretBounds = CaretBounds;
|
||||
caretBounds.X += prefixSize.X;
|
||||
|
||||
float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.7f);
|
||||
alpha = alpha * alpha * alpha * alpha * alpha * alpha;
|
||||
Render2D.FillRectangle(caretBounds, CaretColor * alpha);
|
||||
}
|
||||
|
||||
// Restore rendering state
|
||||
if (useViewOffset)
|
||||
Render2D.PopTransform();
|
||||
Render2D.PopClip();
|
||||
}
|
||||
|
||||
public override void Paste()
|
||||
{
|
||||
if (IsReadOnly)
|
||||
return;
|
||||
|
||||
string clipboardText = Clipboard.Text;
|
||||
// Handle newlines in clipboard text
|
||||
if (!string.IsNullOrEmpty(clipboardText))
|
||||
{
|
||||
// TODO: probably better to just split these lines and parse each line separately
|
||||
clipboardText = clipboardText.Replace("\r\n", "");
|
||||
clipboardText = clipboardText.Replace("\n", "");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(clipboardText))
|
||||
{
|
||||
int right = SelectionRight;
|
||||
Insert(clipboardText);
|
||||
SetSelection(Mathf.Max(right, 0) + clipboardText.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
[Flags]
|
||||
public enum ConsoleFlags
|
||||
{
|
||||
NoSerialize = 1, // Value does not persist
|
||||
[Flags]
|
||||
public enum ConsoleFlags
|
||||
{
|
||||
NoSerialize = 1, // Value does not persist
|
||||
|
||||
Alias = NoSerialize,
|
||||
}
|
||||
Alias = NoSerialize
|
||||
}
|
||||
|
||||
internal struct ConsoleVariable
|
||||
{
|
||||
public string name { get; private set; }
|
||||
public ConsoleFlags flags { get; private set; }
|
||||
internal struct ConsoleVariable
|
||||
{
|
||||
public string name { get; }
|
||||
public ConsoleFlags flags { get; }
|
||||
|
||||
private FieldInfo field;
|
||||
private MethodInfo getter;
|
||||
private MethodInfo setter;
|
||||
private readonly FieldInfo field;
|
||||
private readonly MethodInfo getter;
|
||||
private readonly MethodInfo setter;
|
||||
|
||||
public ConsoleVariable(string name, ConsoleFlags flags, FieldInfo field)
|
||||
{
|
||||
this.name = name;
|
||||
this.flags = flags;
|
||||
this.field = field;
|
||||
this.getter = null;
|
||||
this.setter = null;
|
||||
}
|
||||
public ConsoleVariable(string name, ConsoleFlags flags, FieldInfo field)
|
||||
{
|
||||
this.name = name;
|
||||
this.flags = flags;
|
||||
this.field = field;
|
||||
getter = null;
|
||||
setter = null;
|
||||
}
|
||||
|
||||
public ConsoleVariable(string name, ConsoleFlags flags, MethodInfo getter, MethodInfo setter)
|
||||
{
|
||||
this.name = name;
|
||||
this.flags = flags;
|
||||
this.field = null;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
}
|
||||
public ConsoleVariable(string name, ConsoleFlags flags, MethodInfo getter, MethodInfo setter)
|
||||
{
|
||||
this.name = name;
|
||||
this.flags = flags;
|
||||
field = null;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
public string GetValueString()
|
||||
{
|
||||
var type = field != null ? field.FieldType : getter.ReturnType;
|
||||
if (type == typeof(string))
|
||||
{
|
||||
if (field != null)
|
||||
return (string) field.GetValue(null);
|
||||
else if (setter != null)
|
||||
return (string) getter.Invoke(null, null);
|
||||
}
|
||||
else
|
||||
throw new Exception("cvar is not type of string");
|
||||
public string GetValueString()
|
||||
{
|
||||
Type type = field != null ? field.FieldType : getter.ReturnType;
|
||||
if (type == typeof(string))
|
||||
{
|
||||
if (field != null)
|
||||
return (string)field.GetValue(null);
|
||||
if (setter != null)
|
||||
return (string)getter.Invoke(null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("cvar is not type of string");
|
||||
}
|
||||
|
||||
throw new Exception("GetValueString no field or getter specified");
|
||||
}
|
||||
throw new Exception("GetValueString no field or getter specified");
|
||||
}
|
||||
|
||||
public void SetValue(string value)
|
||||
{
|
||||
var type = field != null ? field.FieldType : getter.ReturnType;
|
||||
if (type == typeof(string))
|
||||
{
|
||||
if (field != null)
|
||||
field.SetValue(null, value);
|
||||
else if (setter != null)
|
||||
setter.Invoke(null, new object[] {value});
|
||||
}
|
||||
else
|
||||
throw new Exception("Unsupported type for SetValue: " + type.Name);
|
||||
}
|
||||
}
|
||||
public void SetValue(string value)
|
||||
{
|
||||
Type type = field != null ? field.FieldType : getter.ReturnType;
|
||||
if (type == typeof(string))
|
||||
{
|
||||
if (field != null)
|
||||
field.SetValue(null, value);
|
||||
else if (setter != null)
|
||||
setter.Invoke(null, new object[] { value });
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unsupported type for SetValue: " + type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,217 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FlaxEngine;
|
||||
using FidelityFX;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
// Holds Console variables and commands to control engine behaviour
|
||||
public static class EngineSubsystem
|
||||
{
|
||||
[ConsoleSubsystemInitializer]
|
||||
public static void Initialize()
|
||||
{
|
||||
}
|
||||
// Holds Console variables and commands to control engine behaviour
|
||||
public static class EngineSubsystem
|
||||
{
|
||||
private static FSR _fsrPlugin;
|
||||
|
||||
[ConsoleCommand("quit", "exit")]
|
||||
public static void ExitCommand()
|
||||
{
|
||||
Engine.RequestExit();
|
||||
}
|
||||
// TODO: this should manually set all postprocessing values to 0 or disabled
|
||||
/*[ConsoleVariable("r_postprocessing")]
|
||||
public static string PostProcessing
|
||||
{
|
||||
get
|
||||
{
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
return postFx.CameraArtifacts.OverrideFlags.ToString();
|
||||
return "";
|
||||
}
|
||||
set
|
||||
{
|
||||
bool valueBoolean = false;
|
||||
if (int.TryParse(value, out int valueInt))
|
||||
valueBoolean = valueInt != 0;
|
||||
else
|
||||
return;
|
||||
|
||||
[ConsoleCommand("debuglog")]
|
||||
public static void DebugLogCommand(string[] text)
|
||||
{
|
||||
Debug.Log(string.Join(" ", text));
|
||||
}
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
{
|
||||
var cameraArtifacts = postFx.CameraArtifacts;
|
||||
cameraArtifacts.OverrideFlags = valueBoolean ? CameraArtifactsSettingsOverride.None : CameraArtifactsSettingsOverride.All;
|
||||
postFx.CameraArtifacts = cameraArtifacts;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// TODO: this should manually set all postprocessing values to 0 or disabled
|
||||
/*[ConsoleVariable("r_postprocessing")]
|
||||
public static string PostProcessing
|
||||
{
|
||||
get
|
||||
{
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
return postFx.CameraArtifacts.OverrideFlags.ToString();
|
||||
return "";
|
||||
}
|
||||
set
|
||||
{
|
||||
bool valueBoolean = false;
|
||||
if (int.TryParse(value, out int valueInt))
|
||||
valueBoolean = valueInt != 0;
|
||||
else
|
||||
return;
|
||||
[ConsoleVariable("r_vignette")]
|
||||
public static string Vignette
|
||||
{
|
||||
get
|
||||
{
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
return postFx.CameraArtifacts.VignetteIntensity.ToString();
|
||||
return "";
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.0f, 2.0f);
|
||||
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
{
|
||||
var cameraArtifacts = postFx.CameraArtifacts;
|
||||
cameraArtifacts.OverrideFlags = valueBoolean ? CameraArtifactsSettingsOverride.None : CameraArtifactsSettingsOverride.All;
|
||||
postFx.CameraArtifacts = cameraArtifacts;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
CameraArtifactsSettings cameraArtifacts = postFx.CameraArtifacts;
|
||||
cameraArtifacts.VignetteIntensity = valueFloat;
|
||||
postFx.CameraArtifacts = cameraArtifacts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_vignette")]
|
||||
public static string Vignette
|
||||
{
|
||||
get
|
||||
{
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
return postFx.CameraArtifacts.VignetteIntensity.ToString();
|
||||
return "";
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
PostFxVolume postFx = Level.FindActor<PostFxVolume>();
|
||||
if (postFx != null)
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.0f, 2.0f);
|
||||
[ConsoleVariable("cl_maxfps")]
|
||||
public static string MaxFps
|
||||
{
|
||||
get => Time.UpdateFPS.ToString();
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
if (valueFloat <= 0.0f)
|
||||
valueFloat = 0.0f;
|
||||
else
|
||||
valueFloat = Mathf.Clamp(valueFloat, 10f, 99999999999.0f);
|
||||
|
||||
var cameraArtifacts = postFx.CameraArtifacts;
|
||||
cameraArtifacts.VignetteIntensity = valueFloat;
|
||||
postFx.CameraArtifacts = cameraArtifacts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Time.UpdateFPS != valueFloat)
|
||||
Time.UpdateFPS = valueFloat;
|
||||
if (Time.DrawFPS != valueFloat)
|
||||
Time.DrawFPS = valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("cl_maxfps")]
|
||||
public static string MaxFps
|
||||
{
|
||||
get { return Time.UpdateFPS.ToString(); }
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
if (valueFloat <= 0.0f)
|
||||
valueFloat = 0.0f;
|
||||
else
|
||||
valueFloat = Mathf.Clamp(valueFloat, 10f, 99999999999.0f);
|
||||
[ConsoleVariable("r_renderscale")]
|
||||
public static string RenderScale
|
||||
{
|
||||
get => MainRenderTask.Instance.RenderingPercentage.ToString();
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.00001f, 4.0f);
|
||||
MainRenderTask.Instance.RenderingPercentage = valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Time.UpdateFPS != valueFloat)
|
||||
Time.UpdateFPS = valueFloat;
|
||||
if (Time.DrawFPS != valueFloat)
|
||||
Time.DrawFPS = valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static FSR FsrPlugin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_fsrPlugin == null)
|
||||
_fsrPlugin = PluginManager.GetPlugin<FSR>();
|
||||
return _fsrPlugin;
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("r_renderscale")]
|
||||
public static string RenderScale
|
||||
{
|
||||
get
|
||||
{
|
||||
return MainRenderTask.Instance.RenderingPercentage.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.00001f, 4.0f);
|
||||
MainRenderTask.Instance.RenderingPercentage = valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: r_upscaling
|
||||
[ConsoleVariable("r_fsr_enabled")]
|
||||
public static string FsrEnabled
|
||||
{
|
||||
get => FsrPlugin.PostFx.Enabled ? "1" : "0";
|
||||
set
|
||||
{
|
||||
bool boolValue = false;
|
||||
if (int.TryParse(value, out int intValue))
|
||||
boolValue = intValue != 0;
|
||||
else if (float.TryParse(value, out float valueFloat))
|
||||
boolValue = valueFloat != 0f;
|
||||
|
||||
private static FSR _fsrPlugin;
|
||||
public static FSR FsrPlugin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_fsrPlugin == null)
|
||||
_fsrPlugin = PluginManager.GetPlugin<FSR>();
|
||||
return _fsrPlugin;
|
||||
}
|
||||
}
|
||||
FsrPlugin.PostFx.Enabled = boolValue;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: r_upscaling
|
||||
[ConsoleVariable("r_fsr_enabled")]
|
||||
public static string FsrEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return FsrPlugin.PostFx.Enabled ? "1" : "0";
|
||||
}
|
||||
set
|
||||
{
|
||||
bool boolValue = false;
|
||||
if (int.TryParse(value, out int intValue))
|
||||
boolValue = intValue != 0;
|
||||
else if (float.TryParse(value, out float valueFloat))
|
||||
boolValue = valueFloat != 0f;
|
||||
[ConsoleVariable("r_fsr_sharpness")]
|
||||
public static string FsrSharpness
|
||||
{
|
||||
get
|
||||
{
|
||||
// In shader, the value of 0 is the max sharpness...
|
||||
float sharpness = 2.0f - FsrPlugin.PostFx.Sharpness;
|
||||
return sharpness.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0f, 2.0f);
|
||||
FsrPlugin.PostFx.Sharpness = 2.0f - valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FsrPlugin.PostFx.Enabled = boolValue;
|
||||
}
|
||||
}
|
||||
[ConsoleVariable("cl_showweapon")]
|
||||
public static string ShowWeapon
|
||||
{
|
||||
get => Level.FindActor("ViewModelCamera").IsActive ? "1" : "0";
|
||||
set
|
||||
{
|
||||
bool boolValue = false;
|
||||
if (int.TryParse(value, out int intValue))
|
||||
boolValue = intValue != 0;
|
||||
else if (float.TryParse(value, out float valueFloat))
|
||||
boolValue = valueFloat != 0f;
|
||||
|
||||
[ConsoleVariable("r_fsr_sharpness")]
|
||||
public static string FsrSharpness
|
||||
{
|
||||
get
|
||||
{
|
||||
// In shader, the value of 0 is the max sharpness...
|
||||
float sharpness = 2.0f - FsrPlugin.PostFx.Sharpness;
|
||||
return sharpness.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0f, 2.0f);
|
||||
FsrPlugin.PostFx.Sharpness = 2.0f - valueFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleVariable("cl_showweapon")]
|
||||
public static string ShowWeapon
|
||||
{
|
||||
get
|
||||
{
|
||||
return Level.FindActor("ViewModelCamera").IsActive ? "1" : "0";
|
||||
}
|
||||
set
|
||||
{
|
||||
bool boolValue = false;
|
||||
if (int.TryParse(value, out int intValue))
|
||||
boolValue = intValue != 0;
|
||||
else if (float.TryParse(value, out float valueFloat))
|
||||
boolValue = valueFloat != 0f;
|
||||
|
||||
Level.FindActor("ViewModelCamera").IsActive = boolValue;
|
||||
}
|
||||
}
|
||||
Level.FindActor("ViewModelCamera").IsActive = boolValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Horizontal field of view of the Camera
|
||||
[ConsoleVariable("fov")]
|
||||
public static string CameraFov
|
||||
{
|
||||
get
|
||||
{
|
||||
float valueFloat = Level.FindActor("PlayerCamera").As<Camera>().FieldOfView;
|
||||
float horizontalFov = (float)(180.0f / Math.PI * (2*Math.Atan((4f/3f) * Math.Tan(Math.PI / 180.0f * valueFloat / 2.0f))));
|
||||
return horizontalFov.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.01f, 360.0f);
|
||||
// Horizontal field of view of the Camera
|
||||
[ConsoleVariable("fov")]
|
||||
public static string CameraFov
|
||||
{
|
||||
get
|
||||
{
|
||||
float valueFloat = Level.FindActor("PlayerCamera").As<Camera>().FieldOfView;
|
||||
float horizontalFov = (float)(180.0f / Math.PI *
|
||||
(2 * Math.Atan(4f / 3f *
|
||||
Math.Tan(Math.PI / 180.0f * valueFloat / 2.0f))));
|
||||
return horizontalFov.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.TryParse(value, out float valueFloat))
|
||||
{
|
||||
valueFloat = Mathf.Clamp(valueFloat, 0.01f, 360.0f);
|
||||
|
||||
float verticalFov = (float)(180.0f / Math.PI * (2*Math.Atan((3f/4f) * Math.Tan(Math.PI / 180.0f * valueFloat / 2.0f))));
|
||||
Level.FindActor("PlayerCamera").As<Camera>().FieldOfView = verticalFov;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float verticalFov = (float)(180.0f / Math.PI *
|
||||
(2 * Math.Atan(3f / 4f *
|
||||
Math.Tan(Math.PI / 180.0f * valueFloat / 2.0f))));
|
||||
Level.FindActor("PlayerCamera").As<Camera>().FieldOfView = verticalFov;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleSubsystemInitializer]
|
||||
public static void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
[ConsoleCommand("quit", "exit")]
|
||||
public static void ExitCommand()
|
||||
{
|
||||
Engine.RequestExit();
|
||||
}
|
||||
|
||||
[ConsoleCommand("debuglog")]
|
||||
public static void DebugLogCommand(string[] text)
|
||||
{
|
||||
Debug.Log(string.Join(" ", text));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,11 @@ namespace Game
|
||||
{
|
||||
public static class Utilities
|
||||
{
|
||||
public static ScopeProfiler ProfileScope(string eventName)
|
||||
{
|
||||
return new ScopeProfiler(eventName);
|
||||
}
|
||||
|
||||
public class ScopeProfiler : IDisposable
|
||||
{
|
||||
public ScopeProfiler(string eventName)
|
||||
@@ -17,10 +22,5 @@ namespace Game
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public static ScopeProfiler ProfileScope(string eventName)
|
||||
{
|
||||
return new ScopeProfiler(eventName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,5 @@
|
||||
{
|
||||
public abstract class GameMode
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using Cabrito;
|
||||
using System;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Networking;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
@@ -8,6 +10,19 @@ namespace Game
|
||||
public static void Init()
|
||||
{
|
||||
NetworkManager.OnMessage += OnClientConnected;
|
||||
Level.SceneLoaded += OnLevelLoaded;
|
||||
Console.Print("level was loaded: " + Level.IsAnySceneLoaded);
|
||||
}
|
||||
|
||||
public static void Cleanup()
|
||||
{
|
||||
NetworkManager.OnMessage -= OnClientConnected;
|
||||
Level.SceneLoaded -= OnLevelLoaded;
|
||||
}
|
||||
|
||||
public static void OnLevelLoaded(Scene scene, Guid assetGuid)
|
||||
{
|
||||
Console.Print("level loaded");
|
||||
}
|
||||
|
||||
public static bool OnClientConnected(NetworkMessage message)
|
||||
|
||||
@@ -1,108 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
|
||||
namespace Cabrito
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
public class FpsScript : Script
|
||||
{
|
||||
public UIControl control;
|
||||
Label label;
|
||||
[ExecuteInEditMode]
|
||||
public class FpsScript : Script
|
||||
{
|
||||
private const double updateInterval = 0.25;
|
||||
private const double drawInterval = 0.25;
|
||||
private const double physicsInterval = 0.25;
|
||||
|
||||
Stopwatch sw;
|
||||
double updateTimeAvg = 0.0;
|
||||
ulong updateTimeCount;
|
||||
const double updateInterval = 0.25;
|
||||
double updateAccumTime = 0.0;
|
||||
private double conTime;
|
||||
public UIControl control;
|
||||
|
||||
Stopwatch sw2;
|
||||
double drawTimeAvg = 0.0;
|
||||
ulong drawTimeCount;
|
||||
const double drawInterval = 0.25;
|
||||
double drawAccumTime = 0.0;
|
||||
private string currentRenderer = "Unknown";
|
||||
private double drawAccumTime;
|
||||
private double drawTimeAvg;
|
||||
private ulong drawTimeCount;
|
||||
private Label label;
|
||||
private double physicsAccumTime;
|
||||
private double physicsTimeAvg;
|
||||
private ulong physicsTimeCount;
|
||||
|
||||
Stopwatch sw3;
|
||||
double physicsTimeAvg = 0.0;
|
||||
ulong physicsTimeCount;
|
||||
const double physicsInterval = 0.25;
|
||||
double physicsAccumTime = 0.0;
|
||||
private Stopwatch sw;
|
||||
|
||||
Stopwatch sw0;
|
||||
private Stopwatch sw0;
|
||||
|
||||
string currentRenderer = "Unknown";
|
||||
private Stopwatch sw2;
|
||||
|
||||
RenderTask t;
|
||||
private Stopwatch sw3;
|
||||
|
||||
TimeSettings timeSettings;
|
||||
private RenderTask t;
|
||||
|
||||
public override void OnAwake()
|
||||
{
|
||||
label = (Label) control.Control;
|
||||
private TimeSettings timeSettings;
|
||||
private double updateAccumTime;
|
||||
private double updateTimeAvg;
|
||||
private ulong updateTimeCount;
|
||||
|
||||
sw = Stopwatch.StartNew();
|
||||
sw2 = Stopwatch.StartNew();
|
||||
sw3 = Stopwatch.StartNew();
|
||||
sw0 = Stopwatch.StartNew();
|
||||
public override void OnAwake()
|
||||
{
|
||||
label = (Label)control.Control;
|
||||
|
||||
currentRenderer = GPUDevice.Instance.RendererType.ToString();
|
||||
sw = Stopwatch.StartNew();
|
||||
sw2 = Stopwatch.StartNew();
|
||||
sw3 = Stopwatch.StartNew();
|
||||
sw0 = Stopwatch.StartNew();
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
//Destroy(t);
|
||||
t = new RenderTask();
|
||||
t.Render += OnDraw;
|
||||
}
|
||||
currentRenderer = GPUDevice.Instance.RendererType.ToString();
|
||||
|
||||
var settings = FlaxEditor.Content.Settings.GameSettings.Load();
|
||||
timeSettings = settings.Time.CreateInstance<FlaxEditor.Content.Settings.TimeSettings>();
|
||||
}
|
||||
if (t == null)
|
||||
{
|
||||
//Destroy(t);
|
||||
t = new RenderTask();
|
||||
t.Render += OnDraw;
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
Destroy(t);
|
||||
t = null;
|
||||
}
|
||||
GameSettings settings = GameSettings.Load();
|
||||
timeSettings = settings.Time.CreateInstance<TimeSettings>();
|
||||
}
|
||||
|
||||
double conTime = 0.0;
|
||||
public override void OnDestroy()
|
||||
{
|
||||
Destroy(t);
|
||||
t = null;
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
updateAccumTime += Time.DeltaTime;
|
||||
updateTimeCount++;
|
||||
double elapsed = sw.Elapsed.TotalSeconds;
|
||||
if (elapsed >= updateInterval)
|
||||
{
|
||||
sw.Restart();
|
||||
updateTimeAvg = elapsed / updateTimeCount;
|
||||
updateTimeCount = 0;
|
||||
public override void OnUpdate()
|
||||
{
|
||||
updateAccumTime += Time.DeltaTime;
|
||||
updateTimeCount++;
|
||||
double elapsed = sw.Elapsed.TotalSeconds;
|
||||
if (elapsed >= updateInterval)
|
||||
{
|
||||
sw.Restart();
|
||||
updateTimeAvg = elapsed / updateTimeCount;
|
||||
updateTimeCount = 0;
|
||||
|
||||
conTime = ((ConsoleContentTextBox.accumDrawTime / ConsoleContentTextBox.accumDrawTimes) * 1000.0);
|
||||
ConsoleContentTextBox.accumDrawTime = 0.0;
|
||||
ConsoleContentTextBox.accumDrawTimes = 0;
|
||||
}
|
||||
conTime = ConsoleContentTextBox.accumDrawTime / ConsoleContentTextBox.accumDrawTimes * 1000.0;
|
||||
ConsoleContentTextBox.accumDrawTime = 0.0;
|
||||
ConsoleContentTextBox.accumDrawTimes = 0;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("eFPS: " + Engine.FramesPerSecond);
|
||||
sb.Append(" uTime: " + sw0.Elapsed.TotalSeconds);
|
||||
sb.Append("\nuFPS: " + ((int) Math.Round(1.0f / updateTimeAvg)));
|
||||
sb.Append(" uTime: " + updateAccumTime);
|
||||
sb.Append("\nrFPS: " + ((int) Math.Round(1.0f / drawTimeAvg)));
|
||||
sb.Append(" rTime: " + drawAccumTime);
|
||||
sb.Append("\npFPS: " + ((int) Math.Round(1.0f / physicsTimeAvg)));
|
||||
sb.Append(" pTime: " + physicsAccumTime);
|
||||
//sb.Append("\nCon: " + conTime.ToString() + "ms");
|
||||
//sb.Append("\nGC memory: " + (GC.GetTotalMemory(false) / 1000000.0f).ToString() + "MB");
|
||||
//sb.Append("\nUpdate profiler: " + updateProfTime.ToString() + "ms");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("eFPS: " + Engine.FramesPerSecond);
|
||||
sb.Append(" uTime: " + sw0.Elapsed.TotalSeconds);
|
||||
sb.Append("\nuFPS: " + (int)Math.Round(1.0f / updateTimeAvg));
|
||||
sb.Append(" uTime: " + updateAccumTime);
|
||||
sb.Append("\nrFPS: " + (int)Math.Round(1.0f / drawTimeAvg));
|
||||
sb.Append(" rTime: " + drawAccumTime);
|
||||
sb.Append("\npFPS: " + (int)Math.Round(1.0f / physicsTimeAvg));
|
||||
sb.Append(" pTime: " + physicsAccumTime);
|
||||
//sb.Append("\nCon: " + conTime.ToString() + "ms");
|
||||
//sb.Append("\nGC memory: " + (GC.GetTotalMemory(false) / 1000000.0f).ToString() + "MB");
|
||||
//sb.Append("\nUpdate profiler: " + updateProfTime.ToString() + "ms");
|
||||
|
||||
#if false
|
||||
#if false
|
||||
#if BUILD_DEVELOPMENT
|
||||
var nameOffset = Marshal.OffsetOf(typeof(ProfilerCPU.Event), "Name0");
|
||||
foreach (var eventsCpu in FlaxEngine.ProfilingTools.EventsCPU)
|
||||
@@ -132,54 +128,54 @@ namespace Cabrito
|
||||
#endif
|
||||
#endif
|
||||
|
||||
((Label) control.Control).Text = sb.ToString();
|
||||
/*if (!Platform.HasFocus)
|
||||
{
|
||||
Time.UpdateFPS = 15;
|
||||
Time.DrawFPS = 15;
|
||||
Time.PhysicsFPS = 15;
|
||||
}
|
||||
((Label)control.Control).Text = sb.ToString();
|
||||
/*if (!Platform.HasFocus)
|
||||
{
|
||||
Time.UpdateFPS = 15;
|
||||
Time.DrawFPS = 15;
|
||||
Time.PhysicsFPS = 15;
|
||||
}
|
||||
#if FLAX_EDITOR
|
||||
else if (!FlaxEditor.Editor.IsPlayMode)
|
||||
{
|
||||
var editorFPS = FlaxEditor.Editor.Instance.Options.Options.General.EditorFPS;
|
||||
Time.UpdateFPS = editorFPS;
|
||||
Time.DrawFPS = editorFPS;
|
||||
Time.PhysicsFPS = timeSettings.PhysicsFPS;
|
||||
}
|
||||
else if (!FlaxEditor.Editor.IsPlayMode)
|
||||
{
|
||||
var editorFPS = FlaxEditor.Editor.Instance.Options.Options.General.EditorFPS;
|
||||
Time.UpdateFPS = editorFPS;
|
||||
Time.DrawFPS = editorFPS;
|
||||
Time.PhysicsFPS = timeSettings.PhysicsFPS;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Time.UpdateFPS = timeSettings.UpdateFPS;
|
||||
Time.DrawFPS = timeSettings.DrawFPS;
|
||||
Time.PhysicsFPS = timeSettings.PhysicsFPS;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
Time.UpdateFPS = timeSettings.UpdateFPS;
|
||||
Time.DrawFPS = timeSettings.DrawFPS;
|
||||
Time.PhysicsFPS = timeSettings.PhysicsFPS;
|
||||
}*/
|
||||
}
|
||||
|
||||
public override void OnFixedUpdate()
|
||||
{
|
||||
physicsAccumTime += Time.DeltaTime;
|
||||
physicsTimeCount++;
|
||||
double elapsed = sw3.Elapsed.TotalSeconds;
|
||||
if (elapsed >= physicsInterval)
|
||||
{
|
||||
sw3.Restart();
|
||||
physicsTimeAvg = elapsed / physicsTimeCount;
|
||||
physicsTimeCount = 0;
|
||||
}
|
||||
}
|
||||
public override void OnFixedUpdate()
|
||||
{
|
||||
physicsAccumTime += Time.DeltaTime;
|
||||
physicsTimeCount++;
|
||||
double elapsed = sw3.Elapsed.TotalSeconds;
|
||||
if (elapsed >= physicsInterval)
|
||||
{
|
||||
sw3.Restart();
|
||||
physicsTimeAvg = elapsed / physicsTimeCount;
|
||||
physicsTimeCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDraw(RenderTask tt, GPUContext context)
|
||||
{
|
||||
drawAccumTime += Time.DeltaTime;
|
||||
drawTimeCount++;
|
||||
double elapsed = sw2.Elapsed.TotalSeconds;
|
||||
if (elapsed >= drawInterval)
|
||||
{
|
||||
sw2.Restart();
|
||||
drawTimeAvg = elapsed / drawTimeCount;
|
||||
drawTimeCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void OnDraw(RenderTask tt, GPUContext context)
|
||||
{
|
||||
drawAccumTime += Time.DeltaTime;
|
||||
drawTimeCount++;
|
||||
double elapsed = sw2.Elapsed.TotalSeconds;
|
||||
if (elapsed >= drawInterval)
|
||||
{
|
||||
sw2.Restart();
|
||||
drawTimeAvg = elapsed / drawTimeCount;
|
||||
drawTimeCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
/// <summary>
|
||||
/// List of supported materials for loaded levels.
|
||||
/// Maps the given texture/shader name to Flax Material/MaterialInstance.
|
||||
/// List of supported materials for loaded levels.
|
||||
/// Maps the given texture/shader name to Flax Material/MaterialInstance.
|
||||
/// </summary>
|
||||
public class BrushMaterialList
|
||||
{
|
||||
@@ -16,12 +14,10 @@ namespace Game
|
||||
|
||||
public struct BrushMaterialListEntry
|
||||
{
|
||||
[EditorOrder(1)]
|
||||
[EditorDisplay(name: "Name")]
|
||||
[EditorOrder(1)] [EditorDisplay(name: "Name")]
|
||||
public string name;
|
||||
|
||||
[EditorOrder(2)]
|
||||
[EditorDisplay(name: "Material")]
|
||||
[EditorOrder(2)] [EditorDisplay(name: "Material")]
|
||||
public MaterialBase asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
||||
#if false
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -855,7 +854,8 @@ namespace Game
|
||||
Vector3 nextVertex = qhe.next.tail;
|
||||
|
||||
Vector3 edgeVector = (nextVertex - vertex).Normalized;
|
||||
Vector3 outVector = Vector3.Cross(-(new Plane(mergedFace.v1, mergedFace.v2, mergedFace.v3).Normal), edgeVector);
|
||||
Vector3 outVector =
|
||||
Vector3.Cross(-(new Plane(mergedFace.v1, mergedFace.v2, mergedFace.v3).Normal), edgeVector);
|
||||
|
||||
HalfEdge testHe = qhe.next;
|
||||
do
|
||||
@@ -1125,7 +1125,7 @@ namespace Game
|
||||
|
||||
foreach (var dface in discardedFaces)
|
||||
{
|
||||
for (int i=0; i<outsideSet.Count; i++)
|
||||
for (int i = 0; i<outsideSet.Count; i++)
|
||||
{
|
||||
if (outsideSet[i].Item1 == dface)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,15 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using FlaxEditor;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Networking;
|
||||
using Console = Cabrito.Console;
|
||||
using Debug = FlaxEngine.Debug;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class NetworkPredictedAttribute : Attribute
|
||||
{
|
||||
public NetworkPredictedAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: insert code to update variables with this attribute?
|
||||
@@ -24,9 +17,6 @@ namespace Game
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class NetworkedAttribute : Attribute
|
||||
{
|
||||
public NetworkedAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// NetworkMulticastAttribute: calls methods marked with this in all clients
|
||||
@@ -34,24 +24,23 @@ namespace Game
|
||||
public enum NetworkMessageType : byte
|
||||
{
|
||||
Handshake = 1,
|
||||
Message,
|
||||
Message
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static partial class NetworkManager
|
||||
{
|
||||
private static bool initialized = false;
|
||||
public delegate bool OnMessageDecl(NetworkMessage message);
|
||||
|
||||
private static bool initialized;
|
||||
|
||||
private static NetworkPeer server;
|
||||
private static NetworkPeer client;
|
||||
|
||||
private static ushort ServerPort = 59183;
|
||||
private static string ServerAddress = null;
|
||||
private static ushort MTU = 1500;
|
||||
private static ushort MaximumClients = 32;
|
||||
|
||||
public delegate bool OnMessageDecl(NetworkMessage message);
|
||||
private static readonly ushort ServerPort = 59183;
|
||||
private static string ServerAddress;
|
||||
private static readonly ushort MTU = 1500;
|
||||
private static readonly ushort MaximumClients = 32;
|
||||
public static OnMessageDecl OnMessage;
|
||||
|
||||
public static void Init()
|
||||
@@ -79,14 +68,18 @@ namespace Game
|
||||
|
||||
initialized = true;
|
||||
GameModeManager.Init(); // FIXME
|
||||
|
||||
#if FLAX_EDITOR
|
||||
Editor.Instance.PlayModeEnd += Cleanup;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Deinitialize()
|
||||
public static void Cleanup()
|
||||
{
|
||||
if (server != null)
|
||||
{
|
||||
Scripting.FixedUpdate -= OnServerUpdate;
|
||||
Scripting.Exit -= Deinitialize;
|
||||
Scripting.Exit -= Cleanup;
|
||||
Level.ActorSpawned -= OnServerActorSpawned;
|
||||
NetworkPeer.ShutdownPeer(server);
|
||||
server = null;
|
||||
@@ -95,11 +88,16 @@ namespace Game
|
||||
if (client != null)
|
||||
{
|
||||
Scripting.FixedUpdate -= OnClientUpdate;
|
||||
Scripting.Exit -= Deinitialize;
|
||||
Scripting.Exit -= Cleanup;
|
||||
Level.ActorSpawned -= OnClientActorSpawned;
|
||||
NetworkPeer.ShutdownPeer(client);
|
||||
client = null;
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
Editor.Instance.PlayModeEnd -= Cleanup;
|
||||
GameModeManager.Cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void OnNetworkMessage(NetworkEvent networkEvent)
|
||||
@@ -117,14 +115,13 @@ namespace Game
|
||||
{
|
||||
case NetworkMessageType.Handshake:
|
||||
{
|
||||
var message = networkEvent.Message.ReadString();
|
||||
string message = networkEvent.Message.ReadString();
|
||||
Console.Print($"Received handshake from {networkEvent.Sender.ConnectionId}, msg: " + message);
|
||||
break;
|
||||
}
|
||||
case NetworkMessageType.Message:
|
||||
{
|
||||
if (OnMessage != null)
|
||||
{
|
||||
foreach (OnMessageDecl func in OnMessage.GetInvocationList()
|
||||
.Cast<OnMessageDecl>().ToArray())
|
||||
{
|
||||
@@ -132,7 +129,7 @@ namespace Game
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
#if FLAX_EDITOR
|
||||
using FlaxEditor;
|
||||
#endif
|
||||
@@ -11,51 +9,51 @@ namespace Game
|
||||
{
|
||||
public class NetworkManagerPlugin : GamePlugin
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Debug.Log("NetworkManagerPlugin Initialize");
|
||||
Console.Init();
|
||||
|
||||
NetworkManager.Init();
|
||||
|
||||
Level.SceneLoaded += (scene, guid) => Console.Print("scene loaded: " + scene.Name);
|
||||
}
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
base.Deinitialize();
|
||||
Debug.Log("NetworkManagerPlugin Deinitialize");
|
||||
}
|
||||
|
||||
public static PluginDescription DescriptionInternal = new PluginDescription()
|
||||
public static PluginDescription DescriptionInternal = new PluginDescription
|
||||
{
|
||||
Author = "Ari Vuollet",
|
||||
Name = "NetworkManager",
|
||||
Description = "NetworkManager for Goake",
|
||||
Version = Version.Parse("0.1.0"),
|
||||
IsAlpha = true,
|
||||
Category = "Game",
|
||||
Category = "Game"
|
||||
};
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Debug.Log("NetworkManagerPlugin Initialize");
|
||||
Console.Init();
|
||||
|
||||
NetworkManager.Init();
|
||||
}
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
base.Deinitialize();
|
||||
Debug.Log("NetworkManagerPlugin Deinitialize");
|
||||
}
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
public class NetworkManagerEditorPlugin : EditorPlugin
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
Debug.Log("NetworkManagerEditorPlugin Initialize");
|
||||
Console.Init();
|
||||
}
|
||||
public class NetworkManagerEditorPlugin : EditorPlugin
|
||||
{
|
||||
public override PluginDescription Description => NetworkManagerPlugin.DescriptionInternal;
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
Debug.Log("NetworkManagerEditorPlugin Deinitialize");
|
||||
}
|
||||
public override Type GamePluginType => typeof(NetworkManagerPlugin);
|
||||
|
||||
public override PluginDescription Description => NetworkManagerPlugin.DescriptionInternal;
|
||||
public override void Initialize()
|
||||
{
|
||||
Debug.Log("NetworkManagerEditorPlugin Initialize");
|
||||
Console.Init();
|
||||
|
||||
public override Type GamePluginType => typeof(NetworkManagerPlugin);
|
||||
}
|
||||
NetworkManager.Init();
|
||||
}
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
Debug.Log("NetworkManagerEditorPlugin Deinitialize");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,29 +1,25 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Networking;
|
||||
using Console = Cabrito.Console;
|
||||
using Debug = FlaxEngine.Debug;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public static partial class NetworkManager
|
||||
{
|
||||
public static uint LocalPlayerClientId { get; private set; } = 0;
|
||||
public static uint LocalPlayerClientId { get; private set; }
|
||||
|
||||
public static bool ConnectServer()
|
||||
{
|
||||
client = NetworkPeer.CreatePeer(new NetworkConfig
|
||||
{
|
||||
NetworkDriver = FlaxEngine.Object.New(typeof(ENetDriver)),
|
||||
NetworkDriver = Object.New(typeof(ENetDriver)),
|
||||
ConnectionsLimit = MaximumClients,
|
||||
MessagePoolSize = 2048,
|
||||
MessageSize = MTU,
|
||||
Address = ServerAddress == "localhost" ? "127.0.0.1" : ServerAddress,
|
||||
Port = ServerPort,
|
||||
Port = ServerPort
|
||||
});
|
||||
if (!client.Connect())
|
||||
{
|
||||
@@ -32,17 +28,16 @@ namespace Game
|
||||
}
|
||||
|
||||
Scripting.FixedUpdate += OnClientUpdate;
|
||||
Scripting.Exit += Deinitialize;
|
||||
Scripting.Exit += Cleanup;
|
||||
Level.ActorSpawned += OnClientActorSpawned;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void OnClientUpdate()
|
||||
{
|
||||
using var _ = Utilities.ProfileScope("NetworkManager_OnClientUpdate");
|
||||
using Utilities.ScopeProfiler _ = Utilities.ProfileScope("NetworkManager_OnClientUpdate");
|
||||
|
||||
while (client.PopEvent(out NetworkEvent networkEvent))
|
||||
{
|
||||
switch (networkEvent.EventType)
|
||||
{
|
||||
case NetworkEventType.Connected:
|
||||
@@ -66,18 +61,17 @@ namespace Game
|
||||
case NetworkEventType.Message:
|
||||
{
|
||||
OnNetworkMessage(networkEvent);
|
||||
|
||||
client.RecycleMessage(networkEvent.Message);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnClientActorSpawned(Actor actor)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Networking;
|
||||
using Console = Cabrito.Console;
|
||||
using Debug = FlaxEngine.Debug;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
@@ -23,7 +20,7 @@ namespace Game
|
||||
ConnectedClients = new List<NetworkConnection>(MaximumClients);
|
||||
server = NetworkPeer.CreatePeer(new NetworkConfig
|
||||
{
|
||||
NetworkDriver = FlaxEngine.Object.New(typeof(ENetDriver)),
|
||||
NetworkDriver = Object.New(typeof(ENetDriver)),
|
||||
ConnectionsLimit = MaximumClients,
|
||||
MessagePoolSize = 2048,
|
||||
MessageSize = MTU,
|
||||
@@ -37,18 +34,18 @@ namespace Game
|
||||
}
|
||||
|
||||
Scripting.FixedUpdate += OnServerUpdate;
|
||||
Scripting.Exit += Deinitialize;
|
||||
Level.ActorSpawned += OnClientActorSpawned;
|
||||
Scripting.Exit += Cleanup;
|
||||
Level.ActorSpawned += OnServerActorSpawned;
|
||||
|
||||
NetworkedTypes = new List<Type>();
|
||||
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
Assembly[] assemblies = currentDomain.GetAssemblies();
|
||||
var assemblies = currentDomain.GetAssemblies();
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
// Skip common assemblies
|
||||
var assemblyName = assembly.GetName().Name;
|
||||
string assemblyName = assembly.GetName().Name;
|
||||
if (assemblyName == "System" ||
|
||||
assemblyName.StartsWith("System.") ||
|
||||
assemblyName.StartsWith("Mono.") ||
|
||||
@@ -58,31 +55,24 @@ namespace Game
|
||||
assemblyName.StartsWith("JetBrains.") ||
|
||||
assemblyName.StartsWith("Microsoft.") ||
|
||||
assemblyName.StartsWith("nunit."))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
foreach (Type type in assembly.GetTypes())
|
||||
if (type.GetCustomAttributes().Any(x => x is NetworkedAttribute))
|
||||
NetworkedTypes.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Type type in NetworkedTypes)
|
||||
{
|
||||
Console.Print("tracking networked type: " + type.Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void OnServerUpdate()
|
||||
{
|
||||
using var _ = Utilities.ProfileScope("NetworkManager_OnServerUpdate");
|
||||
using Utilities.ScopeProfiler _ = Utilities.ProfileScope("NetworkManager_OnServerUpdate");
|
||||
|
||||
while (server.PopEvent(out NetworkEvent networkEvent))
|
||||
{
|
||||
switch (networkEvent.EventType)
|
||||
{
|
||||
case NetworkEventType.Connected:
|
||||
@@ -119,12 +109,11 @@ namespace Game
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnServerActorSpawned(Actor actor)
|
||||
{
|
||||
Console.Print($"actor spawned: {actor.Name} ({actor.TypeName})");
|
||||
//Console.Print($"actor spawned: {actor.Name} ({actor.TypeName})");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class CustomCharacterController : CharacterController
|
||||
{
|
||||
}
|
||||
public class CustomCharacterController : CharacterController
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using Cabrito;
|
||||
using FlaxEngine;
|
||||
using Cabrito;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public static class InputManager
|
||||
{
|
||||
public static bool GetAction(string name)
|
||||
{
|
||||
if (Console.IsOpen)
|
||||
return false;
|
||||
return Input.GetAction(name);
|
||||
}
|
||||
public static class InputManager
|
||||
{
|
||||
public static bool GetAction(string name)
|
||||
{
|
||||
if (Console.IsOpen)
|
||||
return false;
|
||||
return Input.GetAction(name);
|
||||
}
|
||||
|
||||
public static float GetAxis(string name)
|
||||
{
|
||||
if (Console.IsOpen)
|
||||
return 0.0f;
|
||||
return Input.GetAxis(name);
|
||||
}
|
||||
public static float GetAxis(string name)
|
||||
{
|
||||
if (Console.IsOpen)
|
||||
return 0.0f;
|
||||
return Input.GetAxis(name);
|
||||
}
|
||||
|
||||
public static float GetAxisRaw(string name)
|
||||
{
|
||||
if (Console.IsOpen)
|
||||
return 0.0f;
|
||||
return Input.GetAxisRaw(name);
|
||||
}
|
||||
}
|
||||
public static float GetAxisRaw(string name)
|
||||
{
|
||||
if (Console.IsOpen)
|
||||
return 0.0f;
|
||||
return Input.GetAxisRaw(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
using Cabrito;
|
||||
#if FLAX_EDITOR
|
||||
using FlaxEditor.CustomEditors.Dedicated;
|
||||
using FlaxEditor.Scripting;
|
||||
#endif
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
@@ -16,16 +13,16 @@ namespace Game
|
||||
{
|
||||
protected override List<ItemInfo> GetItemsForType(ScriptType type)
|
||||
{
|
||||
List<ItemInfo> items = GetItemsForType(type, type.IsClass, true);
|
||||
var items = GetItemsForType(type, type.IsClass, true);
|
||||
|
||||
// Remove all Rigid Body options
|
||||
items.RemoveAll(x => x.Display.Group == "Rigid Body");
|
||||
|
||||
// Inject scripts editor
|
||||
var scriptsMember = type.GetProperty("Scripts");
|
||||
ScriptMemberInfo scriptsMember = type.GetProperty("Scripts");
|
||||
if (scriptsMember != ScriptMemberInfo.Null)
|
||||
{
|
||||
var item = new ItemInfo(scriptsMember)
|
||||
ItemInfo item = new ItemInfo(scriptsMember)
|
||||
{
|
||||
CustomEditor = new CustomEditorAttribute(typeof(ScriptsEditor))
|
||||
};
|
||||
|
||||
@@ -1,75 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PlayerInputState
|
||||
{
|
||||
public ulong frame;
|
||||
public float viewDeltaX, viewDeltaY;
|
||||
public float moveForward;
|
||||
public float moveRight;
|
||||
public bool attacking;
|
||||
public bool jumping;
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PlayerInputState
|
||||
{
|
||||
public ulong frame;
|
||||
public float viewDeltaX, viewDeltaY;
|
||||
public float moveForward;
|
||||
public float moveRight;
|
||||
public bool attacking;
|
||||
public bool jumping;
|
||||
|
||||
public Vector3 verificationPosition;
|
||||
public Vector3 verificationVelocity;
|
||||
public Vector3 verificationViewAngles;
|
||||
public Quaternion verificationOrientation;
|
||||
}
|
||||
public Vector3 verificationPosition;
|
||||
public Vector3 verificationVelocity;
|
||||
public Vector3 verificationViewAngles;
|
||||
public Quaternion verificationOrientation;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PlayerActorState
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector3 velocity;
|
||||
public Quaternion orientation;
|
||||
public Vector3 viewAngles; // yaw, pitch, roll
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PlayerActorState
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector3 velocity;
|
||||
public Quaternion orientation;
|
||||
public Vector3 viewAngles; // yaw, pitch, roll
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PlayerState
|
||||
{
|
||||
public PlayerInputState input;
|
||||
public PlayerActorState actor;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PlayerState
|
||||
{
|
||||
public PlayerInputState input;
|
||||
public PlayerActorState actor;
|
||||
}
|
||||
|
||||
public class PlayerInput
|
||||
{
|
||||
public PlayerState currentState;
|
||||
public ulong frame;
|
||||
public class PlayerInput
|
||||
{
|
||||
public const byte DemoVer = 1;
|
||||
public PlayerState currentState;
|
||||
public ulong frame;
|
||||
|
||||
public const byte DemoVer = 1;
|
||||
public virtual void OnUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnUpdate()
|
||||
{
|
||||
}
|
||||
public virtual void OnFixedUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnFixedUpdate()
|
||||
{
|
||||
}
|
||||
public virtual void OnEndFrame()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnEndFrame()
|
||||
{
|
||||
}
|
||||
public virtual void RecordCurrentActorState(PlayerActorState actorState)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void RecordCurrentActorState(PlayerActorState actorState)
|
||||
{
|
||||
}
|
||||
public PlayerInputState GetCurrentInputState()
|
||||
{
|
||||
return currentState.input;
|
||||
}
|
||||
|
||||
public PlayerInputState GetCurrentInputState()
|
||||
{
|
||||
return currentState.input;
|
||||
}
|
||||
|
||||
public PlayerActorState GetCurrentActorState()
|
||||
{
|
||||
return currentState.actor;
|
||||
}
|
||||
}
|
||||
public PlayerActorState GetCurrentActorState()
|
||||
{
|
||||
return currentState.actor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,88 +2,89 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class PlayerInputDemo : PlayerInput
|
||||
{
|
||||
protected List<PlayerInputState> buffer = new List<PlayerInputState>();
|
||||
protected IEnumerator<PlayerInputState> bufferEnumerable;
|
||||
public class PlayerInputDemo : PlayerInput
|
||||
{
|
||||
protected List<PlayerInputState> buffer = new List<PlayerInputState>();
|
||||
protected IEnumerator<PlayerInputState> bufferEnumerable;
|
||||
|
||||
public PlayerInputDemo(string demoPath)
|
||||
{
|
||||
if (!File.Exists(demoPath))
|
||||
return;
|
||||
public PlayerInputDemo(string demoPath)
|
||||
{
|
||||
if (!File.Exists(demoPath))
|
||||
return;
|
||||
|
||||
var expectedPlayerInputStateSize = Marshal.SizeOf(typeof(PlayerInputState));
|
||||
int expectedPlayerInputStateSize = Marshal.SizeOf(typeof(PlayerInputState));
|
||||
|
||||
var stream = File.OpenRead(demoPath);
|
||||
var ver = (int)stream.ReadByte();
|
||||
var inputStateSize = (int)stream.ReadByte();
|
||||
if (ver != DemoVer && inputStateSize != expectedPlayerInputStateSize)
|
||||
{
|
||||
Console.Print("demover mismatch: version " + ver + " != " + DemoVer + ", inputStateSize " + inputStateSize + " != " + Marshal.SizeOf(typeof(PlayerInputState)));
|
||||
stream.Close();
|
||||
return;
|
||||
}
|
||||
FileStream stream = File.OpenRead(demoPath);
|
||||
int ver = stream.ReadByte();
|
||||
int inputStateSize = stream.ReadByte();
|
||||
if (ver != DemoVer && inputStateSize != expectedPlayerInputStateSize)
|
||||
{
|
||||
Console.Print("demover mismatch: version " + ver + " != " + DemoVer + ", inputStateSize " +
|
||||
inputStateSize + " != " + Marshal.SizeOf(typeof(PlayerInputState)));
|
||||
stream.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
T RawDeserialize<T>(byte[] rawData, int position)
|
||||
{
|
||||
int rawsize = Marshal.SizeOf(typeof(T));
|
||||
if (rawsize > rawData.Length - position)
|
||||
throw new ArgumentException("Not enough data to fill struct. Array length from position: " + (rawData.Length-position) + ", Struct length: " + rawsize);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
|
||||
Marshal.Copy(rawData, position, buffer, rawsize);
|
||||
T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
return retobj;
|
||||
}
|
||||
T RawDeserialize<T>(byte[] rawData, int position)
|
||||
{
|
||||
int rawsize = Marshal.SizeOf(typeof(T));
|
||||
if (rawsize > rawData.Length - position)
|
||||
throw new ArgumentException("Not enough data to fill struct. Array length from position: " +
|
||||
(rawData.Length - position) + ", Struct length: " + rawsize);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
|
||||
Marshal.Copy(rawData, position, buffer, rawsize);
|
||||
T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
return retobj;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
byte[] b = new byte[expectedPlayerInputStateSize];
|
||||
var readBytes = stream.Read(b, 0, b.Length);
|
||||
if (readBytes < expectedPlayerInputStateSize)
|
||||
break;
|
||||
while (true)
|
||||
{
|
||||
byte[] b = new byte[expectedPlayerInputStateSize];
|
||||
int readBytes = stream.Read(b, 0, b.Length);
|
||||
if (readBytes < expectedPlayerInputStateSize)
|
||||
break;
|
||||
|
||||
buffer.Add(RawDeserialize<PlayerInputState>(b, 0));
|
||||
}
|
||||
buffer.Add(RawDeserialize<PlayerInputState>(b, 0));
|
||||
}
|
||||
|
||||
bufferEnumerable = buffer.GetEnumerator();
|
||||
bufferEnumerable = buffer.GetEnumerator();
|
||||
|
||||
Console.Print("demo numstates: " + buffer.Count);
|
||||
Console.Print("demo numstates: " + buffer.Count);
|
||||
|
||||
OnEndFrame(); // advances to first frame
|
||||
}
|
||||
OnEndFrame(); // advances to first frame
|
||||
}
|
||||
|
||||
public override void OnEndFrame()
|
||||
{
|
||||
// TODO: check if the current state frame matches the current frame number before advancing
|
||||
public override void OnEndFrame()
|
||||
{
|
||||
// TODO: check if the current state frame matches the current frame number before advancing
|
||||
|
||||
/*asdf++;
|
||||
if (asdf < 8)
|
||||
return;*/
|
||||
/*asdf++;
|
||||
if (asdf < 8)
|
||||
return;*/
|
||||
|
||||
if (bufferEnumerable == null || !bufferEnumerable.MoveNext())
|
||||
{
|
||||
if (buffer.Any())
|
||||
{
|
||||
bufferEnumerable.Dispose();
|
||||
bufferEnumerable = null;
|
||||
buffer.Clear();
|
||||
Console.Print("Demo ended");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (bufferEnumerable == null || !bufferEnumerable.MoveNext())
|
||||
{
|
||||
if (buffer.Any())
|
||||
{
|
||||
bufferEnumerable.Dispose();
|
||||
bufferEnumerable = null;
|
||||
buffer.Clear();
|
||||
Console.Print("Demo ended");
|
||||
}
|
||||
|
||||
//var actorState = currentState.actor;
|
||||
currentState.input = bufferEnumerable.Current;
|
||||
//frame++;
|
||||
//currentState.actor = actorState;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//var actorState = currentState.actor;
|
||||
currentState.input = bufferEnumerable.Current;
|
||||
//frame++;
|
||||
//currentState.actor = actorState;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using FlaxEngine;
|
||||
using Console = Cabrito.Console;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class PlayerInputLocal : PlayerInput
|
||||
{
|
||||
protected List<PlayerInputState> buffer = new List<PlayerInputState>();
|
||||
protected FileStream demoFileStream;
|
||||
public class PlayerInputLocal : PlayerInput
|
||||
{
|
||||
protected List<PlayerInputState> buffer = new List<PlayerInputState>();
|
||||
protected FileStream demoFileStream;
|
||||
|
||||
public bool IsRecording { get { return demoFileStream != null; } }
|
||||
public PlayerInputLocal()
|
||||
{
|
||||
}
|
||||
|
||||
public PlayerInputLocal()
|
||||
{
|
||||
}
|
||||
public PlayerInputLocal(string demoPath)
|
||||
{
|
||||
demoFileStream = File.Open(demoPath, FileMode.Create, FileAccess.Write);
|
||||
//stream.Position = 0;
|
||||
//stream.SetLength(0);
|
||||
demoFileStream.WriteByte(DemoVer);
|
||||
demoFileStream.WriteByte((byte)Marshal.SizeOf(typeof(PlayerInputState)));
|
||||
}
|
||||
|
||||
public PlayerInputLocal(string demoPath)
|
||||
{
|
||||
demoFileStream = File.Open(demoPath, FileMode.Create, FileAccess.Write);
|
||||
//stream.Position = 0;
|
||||
//stream.SetLength(0);
|
||||
demoFileStream.WriteByte(DemoVer);
|
||||
demoFileStream.WriteByte((byte)Marshal.SizeOf(typeof(PlayerInputState)));
|
||||
}
|
||||
public bool IsRecording => demoFileStream != null;
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
// Collect all input here
|
||||
// All axis values here should be accumulated
|
||||
currentState.input.viewDeltaX += InputManager.GetAxisRaw("Mouse X");
|
||||
currentState.input.viewDeltaY += InputManager.GetAxisRaw("Mouse Y");
|
||||
currentState.input.viewDeltaX += InputManager.GetAxisRaw("LookRight") * Time.DeltaTime * 100;
|
||||
currentState.input.viewDeltaY += -InputManager.GetAxisRaw("LookUp") * Time.DeltaTime * 100;
|
||||
public override void OnUpdate()
|
||||
{
|
||||
// Collect all input here
|
||||
// All axis values here should be accumulated
|
||||
currentState.input.viewDeltaX += InputManager.GetAxisRaw("Mouse X");
|
||||
currentState.input.viewDeltaY += InputManager.GetAxisRaw("Mouse Y");
|
||||
currentState.input.viewDeltaX += InputManager.GetAxisRaw("LookRight") * Time.DeltaTime * 100;
|
||||
currentState.input.viewDeltaY += -InputManager.GetAxisRaw("LookUp") * Time.DeltaTime * 100;
|
||||
|
||||
currentState.input.moveForward = InputManager.GetAxis("Vertical");
|
||||
currentState.input.moveRight = InputManager.GetAxis("Horizontal");
|
||||
currentState.input.attacking = InputManager.GetAction("Attack");
|
||||
currentState.input.jumping = InputManager.GetAction("Jump");
|
||||
}
|
||||
currentState.input.moveForward = InputManager.GetAxis("Vertical");
|
||||
currentState.input.moveRight = InputManager.GetAxis("Horizontal");
|
||||
currentState.input.attacking = InputManager.GetAction("Attack");
|
||||
currentState.input.jumping = InputManager.GetAction("Jump");
|
||||
}
|
||||
|
||||
public override void OnFixedUpdate()
|
||||
{
|
||||
}
|
||||
public override void OnFixedUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnEndFrame()
|
||||
{
|
||||
if (IsRecording)
|
||||
{
|
||||
currentState.input.verificationPosition = currentState.actor.position;
|
||||
currentState.input.verificationVelocity = currentState.actor.velocity;
|
||||
currentState.input.verificationViewAngles = currentState.actor.viewAngles;
|
||||
currentState.input.verificationOrientation = currentState.actor.orientation;
|
||||
public override void OnEndFrame()
|
||||
{
|
||||
if (IsRecording)
|
||||
{
|
||||
currentState.input.verificationPosition = currentState.actor.position;
|
||||
currentState.input.verificationVelocity = currentState.actor.velocity;
|
||||
currentState.input.verificationViewAngles = currentState.actor.viewAngles;
|
||||
currentState.input.verificationOrientation = currentState.actor.orientation;
|
||||
|
||||
currentState.input.frame = frame;
|
||||
buffer.Add(currentState.input);
|
||||
}
|
||||
currentState.input.frame = frame;
|
||||
buffer.Add(currentState.input);
|
||||
}
|
||||
|
||||
// Reset anything accumulatable here
|
||||
currentState.input.viewDeltaX = 0;
|
||||
currentState.input.viewDeltaY = 0;
|
||||
// Reset anything accumulatable here
|
||||
currentState.input.viewDeltaX = 0;
|
||||
currentState.input.viewDeltaY = 0;
|
||||
|
||||
frame++;
|
||||
}
|
||||
frame++;
|
||||
}
|
||||
|
||||
public override void RecordCurrentActorState(PlayerActorState actorState)
|
||||
{
|
||||
if (!IsRecording)
|
||||
return;
|
||||
public override void RecordCurrentActorState(PlayerActorState actorState)
|
||||
{
|
||||
if (!IsRecording)
|
||||
return;
|
||||
|
||||
if (actorState.position.Length <= 0.01)
|
||||
Console.Print("wrong recorded position?");
|
||||
currentState.actor = actorState;
|
||||
}
|
||||
if (actorState.position.Length <= 0.01)
|
||||
Console.Print("wrong recorded position?");
|
||||
currentState.actor = actorState;
|
||||
}
|
||||
|
||||
public void FlushDemo()
|
||||
{
|
||||
if (!IsRecording)
|
||||
return;
|
||||
public void FlushDemo()
|
||||
{
|
||||
if (!IsRecording)
|
||||
return;
|
||||
|
||||
byte[] RawSerialize(object anything)
|
||||
{
|
||||
int rawSize = Marshal.SizeOf(anything);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
|
||||
Marshal.StructureToPtr(anything, buffer, false);
|
||||
byte[] rawDatas = new byte[rawSize];
|
||||
Marshal.Copy(buffer, rawDatas, 0, rawSize);
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
return rawDatas;
|
||||
}
|
||||
byte[] RawSerialize(object anything)
|
||||
{
|
||||
int rawSize = Marshal.SizeOf(anything);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
|
||||
Marshal.StructureToPtr(anything, buffer, false);
|
||||
byte[] rawDatas = new byte[rawSize];
|
||||
Marshal.Copy(buffer, rawDatas, 0, rawSize);
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
return rawDatas;
|
||||
}
|
||||
|
||||
foreach (var state in buffer)
|
||||
{
|
||||
var bytes = RawSerialize(state);
|
||||
demoFileStream.Write(bytes, 0, bytes.Length * sizeof(byte));
|
||||
}
|
||||
foreach (PlayerInputState state in buffer)
|
||||
{
|
||||
byte[] bytes = RawSerialize(state);
|
||||
demoFileStream.Write(bytes, 0, bytes.Length * sizeof(byte));
|
||||
}
|
||||
|
||||
buffer.Clear();
|
||||
}
|
||||
buffer.Clear();
|
||||
}
|
||||
|
||||
public void StopRecording()
|
||||
{
|
||||
if (!IsRecording)
|
||||
return;
|
||||
public void StopRecording()
|
||||
{
|
||||
if (!IsRecording)
|
||||
return;
|
||||
|
||||
FlushDemo();
|
||||
demoFileStream.Close();
|
||||
demoFileStream = null;
|
||||
FlushDemo();
|
||||
demoFileStream.Close();
|
||||
demoFileStream = null;
|
||||
|
||||
Debug.Write(LogType.Info, "demo, wrote states: " + buffer.Count);
|
||||
}
|
||||
}
|
||||
Debug.Write(LogType.Info, "demo, wrote states: " + buffer.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game
|
||||
namespace Game
|
||||
{
|
||||
public class PlayerInputNetwork : PlayerInput
|
||||
{
|
||||
|
||||
}
|
||||
public class PlayerInputNetwork : PlayerInput
|
||||
{
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user