This commit is contained in:
Joalor64 2023-03-05 00:02:05 +00:00 committed by GitHub
commit 3491867fc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 859 additions and 57 deletions

View File

@ -48,6 +48,7 @@
<!-- <define name="PRELOAD_ALL" /> -->
<define name="PRELOAD_ALL" unless="web" />
<define name="NO_PRELOAD_ALL" unless="PRELOAD_ALL"/>
<define name="FUTURE_POLYMOD" if="desktop"/>
<section if="PRELOAD_ALL">
<library name="songs" preload="true" />
@ -95,13 +96,10 @@
<assets path="assets/week6" library="week6" exclude="*.fla|*.mp3" unless="web"/>
<assets path="assets/week7" library="week7" exclude="*.fla|*.ogg" if="web"/>
<assets path="assets/week7" library="week7" exclude="*.fla|*.mp3" unless="web"/>
<!-- <assets path='example_mods' rename='mods' embed='false'/> -->
<template path="example_mods" rename="mods" />
<assets path="mods" if="FUTURE_POLYMOD" />
<assets path='art/readme.txt' rename='do NOT readme.txt' />
<!-- <template path='mods' /> -->
<assets path="CHANGELOG.md" rename='changelog.txt'/>
@ -124,7 +122,7 @@
<haxelib name="flixel-ui" />
<!--haxelib name="newgrounds" unless="switch"/> -->
<haxelib name="faxe" if='switch'/>
<haxelib name="polymod"/>
<haxelib name="polymod-joalor64" if="FUTURE_POLYMOD"/>
<haxelib name="newgrounds"/>
<haxelib name="hxcpp-debug-server" if="desktop debug"/>

View File

@ -1 +0,0 @@
introMod

View File

@ -1,2 +0,0 @@
THIS MOD FOLDER DOES NOT ENTIRELY WORK JUST YET!!!
DONT EXPECT MUCH OUT OF IT RIGHT NOW!!!

View File

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -1,14 +1,21 @@
package;
import flixel.FlxG;
import flixel.graphics.FlxGraphic;
import flixel.graphics.frames.FlxAtlasFrames;
import openfl.utils.AssetType;
import openfl.utils.Assets as OpenFlAssets;
import openfl.media.Sound;
import openfl.utils.Assets;
class Paths
{
inline public static var SOUND_EXT = #if web "mp3" #else "ogg" #end;
public static var currentTrackedAssets:Map<String, FlxGraphic> = [];
public static var currentTrackedSounds:Map<String, Sound> = [];
public static var localTrackedAssets:Array<String> = [];
static var currentLevel:String;
static public function setCurrentLevel(name:String)
@ -16,6 +23,76 @@ class Paths
currentLevel = name.toLowerCase();
}
public static function clearUnusedMemory()
{
for (key in currentTrackedAssets.keys())
{
if (!localTrackedAssets.contains(key) && key != null)
{
var obj = currentTrackedAssets.get(key);
@:privateAccess
if (obj != null)
{
Assets.cache.removeBitmapData(key);
Assets.cache.clearBitmapData(key);
Assets.cache.clear(key);
FlxG.bitmap._cache.remove(key);
obj.destroy();
currentTrackedAssets.remove(key);
}
}
}
for (key in currentTrackedSounds.keys())
{
if (!localTrackedAssets.contains(key) && key != null)
{
var obj = currentTrackedSounds.get(key);
if (obj != null)
{
Assets.cache.removeSound(key);
Assets.cache.clearSounds(key);
Assets.cache.clear(key);
currentTrackedSounds.remove(key);
}
}
}
}
public static function clearStoredMemory()
{
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
var obj = FlxG.bitmap._cache.get(key);
if (obj != null && !currentTrackedAssets.exists(key))
{
Assets.cache.removeBitmapData(key);
Assets.cache.clearBitmapData(key);
Assets.cache.clear(key);
FlxG.bitmap._cache.remove(key);
obj.destroy();
}
}
@:privateAccess
for (key in Assets.cache.getSoundKeys())
{
if (key != null && !currentTrackedSounds.exists(key))
{
var obj = Assets.cache.getSound(key);
if (obj != null)
{
Assets.cache.removeSound(key);
Assets.cache.clearSounds(key);
Assets.cache.clear(key);
}
}
}
localTrackedAssets = [];
}
static function getPath(file:String, type:AssetType, library:Null<String>)
{
if (library != null)
@ -24,11 +101,11 @@ class Paths
if (currentLevel != null)
{
var levelPath = getLibraryPathForce(file, currentLevel);
if (OpenFlAssets.exists(levelPath, type))
if (Assets.exists(levelPath, type))
return levelPath;
levelPath = getLibraryPathForce(file, "shared");
if (OpenFlAssets.exists(levelPath, type))
if (Assets.exists(levelPath, type))
return levelPath;
}
@ -36,82 +113,89 @@ class Paths
}
static public function getLibraryPath(file:String, library = "preload")
{
return if (library == "preload" || library == "default") getPreloadPath(file); else getLibraryPathForce(file, library);
}
inline static function getLibraryPathForce(file:String, library:String)
{
return '$library:assets/$library/$file';
}
inline static function getPreloadPath(file:String)
{
return 'assets/$file';
}
inline static public function file(file:String, type:AssetType = TEXT, ?library:String)
{
return getPath(file, type, library);
}
inline static public function txt(key:String, ?library:String)
{
return getPath('data/$key.txt', TEXT, library);
}
inline static public function xml(key:String, ?library:String)
{
return getPath('data/$key.xml', TEXT, library);
}
inline static public function json(key:String, ?library:String)
{
return getPath('data/$key.json', TEXT, library);
}
static public function sound(key:String, ?library:String)
{
return getPath('sounds/$key.$SOUND_EXT', SOUND, library);
}
static public function sound(key:String, ?library:String, ?cache:Bool = true):Sound
return returnSound('sounds/$key', SOUND, library, cache);
inline static public function soundRandom(key:String, min:Int, max:Int, ?library:String)
{
return sound(key + FlxG.random.int(min, max), library);
}
inline static public function music(key:String, ?library:String)
{
return getPath('music/$key.$SOUND_EXT', MUSIC, library);
}
inline static public function music(key:String, ?library:String, ?cache:Bool = true):Sound
return returnSound('music/$key', MUSIC, library, cache);
inline static public function voices(song:String)
{
return 'songs:assets/songs/${song.toLowerCase()}/Voices.$SOUND_EXT';
}
inline static public function voices(song:String, ?cache:Bool = true):Sound
return returnSound('songs/' + ${song.toLowerCase()} + '/Voices', cache);
inline static public function inst(song:String)
{
return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT';
}
inline static public function inst(song:String, ?cache:Bool = true):Sound
return returnSound('songs/' + ${song.toLowerCase()} + '/Inst', cache);
inline static public function image(key:String, ?library:String)
{
return getPath('images/$key.png', IMAGE, library);
}
inline static public function image(key:String, ?library:String, ?cache:Bool = true):FlxGraphic
return returnGraphic('images/$key', IMAGE, library, cache);
inline static public function font(key:String)
{
return 'assets/fonts/$key';
inline static public function video(key:String)
return 'assets/$key.mp4';
inline static public function getSparrowAtlas(key:String, ?library:String, ?cache:Bool = true)
return FlxAtlasFrames.fromSparrow(returnGraphic('images/$key', cache), xml('images/$key'));
inline static public function getPackerAtlas(key:String, ?library:String, ?cache:Bool = true)
return FlxAtlasFrames.fromSpriteSheetPacker(returnGraphic('images/$key', cache), txt('images/$key'));
public static function returnGraphic(key:String, ?cache:Bool = true):FlxGraphic
{
var path:String = 'assets/$key.png';
if (Assets.exists(path, IMAGE, library))
{
if (!currentTrackedAssets.exists(path))
{
var graphic:FlxGraphic = FlxGraphic.fromBitmapData(Assets.getBitmapData(path), false, path, cache);
graphic.persist = true;
currentTrackedAssets.set(path, graphic);
}
localTrackedAssets.push(path);
return currentTrackedAssets.get(path);
}
trace('$key its null');
return null;
}
inline static public function getSparrowAtlas(key:String, ?library:String)
public static function returnSound(key:String, ?cache:Bool = true):Sound
{
return FlxAtlasFrames.fromSparrow(image(key, library), file('images/$key.xml', library));
}
if (Assets.exists('assets/$key.$SOUND_EXT', SOUND, library))
{
var path:String = 'assets/$key.$SOUND_EXT';
if (!currentTrackedSounds.exists(path))
currentTrackedSounds.set(path, Assets.getSound(path, library, cache));
inline static public function getPackerAtlas(key:String, ?library:String)
{
return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library));
localTrackedAssets.push(path);
return currentTrackedSounds.get(path);
}
trace('$key its null');
return null;
}
}

View File

@ -45,6 +45,8 @@ import sys.io.File;
import sys.thread.Thread;
#end
import core.ModCore;
class TitleState extends MusicBeatState
{
public static var initialized:Bool = false;
@ -69,9 +71,8 @@ class TitleState extends MusicBeatState
override public function create():Void
{
#if polymod
polymod.Polymod.init({modRoot: "mods", dirs: ['introMod'], framework: OPENFL});
// FlxG.bitmap.clearCache();
#if (polymod && FUTURE_POLYMOD)
ModCore.reload();
#end
startedIntro = false;

109
source/core/ModCore.hx Normal file
View File

@ -0,0 +1,109 @@
package core;
import flixel.FlxG;
import openfl.Lib;
#if FUTURE_POLYMOD
import polymod.Polymod;
import polymod.backends.PolymodAssets.PolymodAssetType;
import polymod.format.ParseRules;
#end
/**
* Class based originally from ChainSaw Engine.
* Credits: MAJigsaw77.
*/
class ModCore
{
private static final MOD_DIR:String = 'mods';
#if FUTURE_POLYMOD
private static final extensions:Map<String, PolymodAssetType> = [
'mp3' => AUDIO_GENERIC,
'ogg' => AUDIO_GENERIC,
'png' => IMAGE,
'xml' => TEXT,
'txt' => TEXT,
'ttf' => FONT,
'otf' => FONT,
'mp4' => VIDEO
];
public static var trackedMods:Array<ModMetadata> = [];
#end
public static function reload():Void
{
#if FUTURE_POLYMOD
trace('Reloading Polymod...');
loadMods(getMods());
#else
trace("Polymod reloading is not supported on your Platform!");
#end
}
#if FUTURE_POLYMOD
public static function loadMods(folders:Array<String>):Void
{
var loadedModlist:Array<ModMetadata> = Polymod.init({
modRoot: MOD_DIR,
dirs: folders,
framework: OPENFL,
apiVersion: Lib.application.meta.get('version'),
errorCallback: onError,
parseRules: getParseRules(),
extensionMap: extensions,
ignoredFiles: Polymod.getDefaultIgnoreList()
});
if (loadedModlist == null) return;
trace('Loading Successful, ${loadedModlist.length} / ${folders.length} new mods.');
for (mod in loadedModlist)
trace('Name: ${mod.title}, [${mod.id}]');
}
public static function getMods():Array<String>
{
trackedMods = [];
var daList:Array<String> = [];
trace('Searching for Mods...');
for (i in Polymod.scan(MOD_DIR, '*.*.*', onError))
{
if (i != null){
trackedMods.push(i);
daList.push(i.id);
}
}
if (daList != null && daList.length > 0)
trace('Found ${daList.length} new mods.');
return daList != null && daList.length > 0 ? daList : [];
}
public static function getParseRules():ParseRules
{
var output:ParseRules = ParseRules.getDefault();
output.addType("txt", TextFileFormat.LINES);
output.addType("hx", TextFileFormat.PLAINTEXT);
return output != null ? output : null;
}
static function onError(error:PolymodError):Void
{
switch (error.severity)
{
case NOTICE:
trace(error.message);
case WARNING:
trace(error.message);
case ERROR:
trace(error.message);
}
}
#end
}

View File

@ -0,0 +1,415 @@
package openfl.utils;
import openfl.display.BitmapData;
import openfl.media.Sound;
import openfl.text.Font;
#if lime
import lime.utils.Assets as LimeAssets;
#end
/**
The AssetCache class is the default cache implementation used
by openfl.utils.Assets, objects will be cached for the lifetime
of the application unless removed explicitly, or using Assets
`unloadLibrary`
**/
#if !openfl_debug
@:fileXml('tags="haxe,release"')
@:noDebug
#end
class AssetCache implements IAssetCache
{
/**
Whether caching is currently enabled.
**/
public var enabled(get, set):Bool;
/**
Internal
**/
@:noCompletion @:dox(hide) public var bitmapData:Map<String, BitmapData>;
/**
Internal
**/
@:noCompletion @:dox(hide) public var font:Map<String, Font>;
/**
Internal
**/
@:noCompletion @:dox(hide) public var sound:Map<String, Sound>;
@:noCompletion private var __enabled:Bool = true;
#if openfljs
@:noCompletion private static function __init__()
{
untyped global.Object.defineProperty(AssetCache.prototype, "enabled", {
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_enabled (); }"),
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_enabled (v); }")
});
}
#end
/**
Creates a new AssetCache instance.
**/
public function new()
{
bitmapData = new Map<String, BitmapData>();
font = new Map<String, Font>();
sound = new Map<String, Sound>();
}
/**
Clears all cached assets, or all assets with an ID that
matches an optional prefix.
For example:
```haxe
Assets.setBitmapData("image1", image1);
Assets.setBitmapData("assets/image2", image2);
Assets.clear("assets"); // will clear image2
Assets.clear("image"); // will clear image1
```
@param prefix A ID prefix
**/
public function clear(prefix:String = null):Void
{
clearBitmapData(prefix);
clearFonts(prefix);
clearSounds(prefix);
}
/**
Clears all cached Bitmap assets, or all assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function clearBitmapData(prefix:String = null):Void
{
if (prefix == null)
{
bitmapData = new Map<String, BitmapData>();
}
else
{
for (key in getBitmapKeys(prefix))
{
removeBitmapData(key);
}
}
}
/**
Clears all cached Font assets, or all assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function clearFonts(prefix:String = null):Void
{
if (prefix == null)
{
font = new Map<String, Font>();
}
else
{
for (key in getFontKeys(prefix))
{
removeFont(key);
}
}
}
/**
Clears all cached Sound assets, or all assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function clearSounds(prefix:String = null):Void
{
if (prefix == null)
{
sound = new Map<String, Sound>();
}
else
{
for (key in getSoundKeys(prefix))
{
removeSound(key);
}
}
}
/**
Returns the IDs of all assets with an ID that
matches an optional prefix.
For example:
```haxe
Assets.setBitmapData("image1", image1);
Assets.setBitmapData("assets/image2", image2);
Assets.getKeys("assets"); // will return ["assets/image2"]
Assets.getKeys("image"); // will return ["image1"]
```
@param prefix A ID prefix
**/
public function getKeys(prefix:String = null):Array<String>
{
var result:Array<String> = [];
result = result.concat(getBitmapKeys(prefix));
result = result.concat(getFontKeys(prefix));
result = result.concat(getSoundKeys(prefix));
return result;
}
/**
Returns the IDs of all BitmapData assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function getBitmapKeys(prefix:String = null):Array<String>
{
var result:Array<String> = [];
if (prefix == null)
{
for (key in bitmapData.keys())
{
result.push(key);
}
}
else
{
for (key in bitmapData.keys())
{
if (StringTools.startsWith(key, prefix))
{
result.push(key);
}
}
}
return result;
}
/**
Returns the IDs of all Font assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function getFontKeys(prefix:String = null):Array<String>
{
var result:Array<String> = [];
if (prefix == null)
{
for (key in font.keys())
{
result.push(key);
}
}
else
{
for (key in font.keys())
{
if (StringTools.startsWith(key, prefix))
{
result.push(key);
}
}
}
return result;
}
/**
Returns the IDs of all Sound assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function getSoundKeys(prefix:String = null):Array<String>
{
var result:Array<String> = [];
if (prefix == null)
{
for (key in sound.keys())
{
result.push(key);
}
}
else
{
for (key in sound.keys())
{
if (StringTools.startsWith(key, prefix))
{
result.push(key);
}
}
}
return result;
}
/**
Retrieves a cached BitmapData.
@param id The ID of the cached BitmapData
@return The cached BitmapData instance
**/
public function getBitmapData(id:String):BitmapData
{
return bitmapData.get(id);
}
/**
Retrieves a cached Font.
@param id The ID of the cached Font
@return The cached Font instance
**/
public function getFont(id:String):Font
{
return font.get(id);
}
/**
Retrieves a cached Sound.
@param id The ID of the cached Sound
@return The cached Sound instance
**/
public function getSound(id:String):Sound
{
return sound.get(id);
}
/**
Checks whether a BitmapData asset is cached.
@param id The ID of a BitmapData asset
@return Whether the object has been cached
**/
public function hasBitmapData(id:String):Bool
{
return bitmapData.exists(id);
}
/**
Checks whether a Font asset is cached.
@param id The ID of a Font asset
@return Whether the object has been cached
**/
public function hasFont(id:String):Bool
{
return font.exists(id);
}
/**
Checks whether a Sound asset is cached.
@param id The ID of a Sound asset
@return Whether the object has been cached
**/
public function hasSound(id:String):Bool
{
return sound.exists(id);
}
/**
Removes a BitmapData from the cache.
@param id The ID of a BitmapData asset
@return `true` if the asset was removed, `false` if it was not in the cache
**/
public function removeBitmapData(id:String):Bool
{
#if lime
LimeAssets.cache.image.remove(id);
#end
return bitmapData.remove(id);
}
/**
Removes a Font from the cache.
@param id The ID of a Font asset
@return `true` if the asset was removed, `false` if it was not in the cache
**/
public function removeFont(id:String):Bool
{
#if lime
LimeAssets.cache.font.remove(id);
#end
return font.remove(id);
}
/**
Removes a Sound from the cache.
@param id The ID of a Sound asset
@return `true` if the asset was removed, `false` if it was not in the cache
**/
public function removeSound(id:String):Bool
{
#if lime
LimeAssets.cache.audio.remove(id);
#end
return sound.remove(id);
}
/**
Adds or replaces a BitmapData asset in the cache.
@param id The ID of a BitmapData asset
@param bitmapData The matching BitmapData instance
**/
public function setBitmapData(id:String, bitmapData:BitmapData):Void
{
this.bitmapData.set(id, bitmapData);
}
/**
Adds or replaces a Font asset in the cache.
@param id The ID of a Font asset
@param bitmapData The matching Font instance
**/
public function setFont(id:String, font:Font):Void
{
this.font.set(id, font);
}
/**
Adds or replaces a Sound asset in the cache.
@param id The ID of a Sound asset
@param bitmapData The matching Sound instance
**/
public function setSound(id:String, sound:Sound):Void
{
this.sound.set(id, sound);
}
// Get & Set Methods
@:noCompletion private function get_enabled():Bool
{
return __enabled;
}
@:noCompletion private function set_enabled(value:Bool):Bool
{
return __enabled = value;
}
}

View File

@ -0,0 +1,198 @@
package openfl.utils;
import openfl.display.BitmapData;
import openfl.media.Sound;
import openfl.text.Font;
/**
The IAssetCache interface provides methods for caching
resources loaded from openfl.utils.Assets to improve
performance.
**/
interface IAssetCache
{
/**
Whether caching is currently enabled.
**/
public var enabled(get, set):Bool;
/**
Clears all cached assets, or all assets with an ID that
matches an optional prefix.
For example:
```haxe
Assets.setBitmapData("image1", image1);
Assets.setBitmapData("assets/image2", image2);
Assets.clear("assets"); // will clear image2
Assets.clear("image"); // will clear image1
```
@param prefix A ID prefix
**/
public function clear(prefix:String = null):Void;
/**
Clears all cached Bitmap assets, or all assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function clearBitmapData(prefix:String = null):Void;
/**
Clears all cached Font assets, or all assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function clearFonts(prefix:String = null):Void;
/**
Clears all cached Sound assets, or all assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function clearSounds(prefix:String = null):Void;
/**
Returns the IDs of all assets with an ID that
matches an optional prefix.
For example:
```haxe
Assets.setBitmapData("image1", image1);
Assets.setBitmapData("assets/image2", image2);
Assets.getKeys("assets"); // will return ["assets/image2"]
Assets.getKeys("image"); // will return ["image1"]
```
@param prefix A ID prefix
**/
public function getKeys(prefix:String = null):Array<String>;
/**
Returns the IDs of all BitmapData assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function getBitmapKeys(prefix:String = null):Array<String>;
/**
Returns the IDs of all Font assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function getFontKeys(prefix:String = null):Array<String>;
/**
Returns the IDs of all Sound assets with an ID that
matches an optional prefix.
@param prefix A ID prefix
**/
public function getSoundKeys(prefix:String = null):Array<String>;
/**
Retrieves a cached BitmapData.
@param id The ID of the cached BitmapData
@return The cached BitmapData instance
**/
public function getBitmapData(id:String):BitmapData;
/**
Retrieves a cached Font.
@param id The ID of the cached Font
@return The cached Font instance
**/
public function getFont(id:String):Font;
/**
Retrieves a cached Sound.
@param id The ID of the cached Sound
@return The cached Sound instance
**/
public function getSound(id:String):Sound;
/**
Checks whether a BitmapData asset is cached.
@param id The ID of a BitmapData asset
@return Whether the object has been cached
**/
public function hasBitmapData(id:String):Bool;
/**
Checks whether a Font asset is cached.
@param id The ID of a Font asset
@return Whether the object has been cached
**/
public function hasFont(id:String):Bool;
/**
Checks whether a Sound asset is cached.
@param id The ID of a Sound asset
@return Whether the object has been cached
**/
public function hasSound(id:String):Bool;
/**
Removes a BitmapData from the cache.
@param id The ID of a BitmapData asset
@return `true` if the asset was removed, `false` if it was not in the cache
**/
public function removeBitmapData(id:String):Bool;
/**
Removes a Font from the cache.
@param id The ID of a Font asset
@return `true` if the asset was removed, `false` if it was not in the cache
**/
public function removeFont(id:String):Bool;
/**
Removes a Sound from the cache.
@param id The ID of a Sound asset
@return `true` if the asset was removed, `false` if it was not in the cache
**/
public function removeSound(id:String):Bool;
/**
Adds or replaces a BitmapData asset in the cache.
@param id The ID of a BitmapData asset
@param bitmapData The matching BitmapData instance
**/
public function setBitmapData(id:String, bitmapData:BitmapData):Void;
/**
Adds or replaces a Font asset in the cache.
@param id The ID of a Font asset
@param bitmapData The matching Font instance
**/
public function setFont(id:String, font:Font):Void;
/**
Adds or replaces a Sound asset in the cache.
@param id The ID of a Sound asset
@param bitmapData The matching Sound instance
**/
public function setSound(id:String, sound:Sound):Void;
}