Page MenuHomeFeedback Tracker

Enfusion Persistence/Database Framework StructAutoCopy problem
Assigned, NormalPublic

Description

When trying to save a persistent scripted state the StructAutoCopy won't write the values from my GameSystem to the ScriptedStateSaveData even though the json is valid, it only works when overriding ReadFrom and ApplyTo functions and settings the values manually

Details

Severity
Major
Resolution
Open
Reproducibility
Always
Operating System
Windows 10 x64
Category
General
Steps To Reproduce
csharp
class EC_PlayerAccount : EDF_DbEntity
{
    private static const int DEFAULT_BALANCE = 1000;
    private static const int DEFAULT_CASH = 500;
    
    private int m_iBalance;
    private int m_iCash;
    
    EC_PlayerAccount EC_PlayerAccount() {};
    
    static EC_PlayerAccount Create()
    {
        EC_PlayerAccount instance = new EC_PlayerAccount();
        instance.m_iBalance = DEFAULT_BALANCE;
        instance.m_iCash = DEFAULT_CASH;
        return instance;
    }
    
    int GetBalance()    { return m_iBalance; }
    int GetCash()         { return m_iCash; }
    
    void AddBalance(int amount) { m_iBalance+=amount; }
    void AddCash(int amount)     { m_iCash+=amount; }
    
    bool RemoveBalance(int amount)
    {
        if (m_iBalance - amount < 0) return false;
        m_iBalance -= amount;
        return true;
    }
    
    bool RemoveCash(int amount)
    {
        if (m_iCash - amount < 0) return false;
        m_iCash -= amount;
        return true;
    }
}
csharp
[EPF_PersistentScriptedStateSettings(EC_MoneySystem), EDF_DbName("MoneySystem")]
class EC_MoneySystemSaveData : EPF_ScriptedStateSaveData
{
    ref map<string, ref EC_PlayerAccount> m_PlayerAccounts;
}; 

class EC_MoneySystem : GameSystem
{
    ref map<string, ref EC_PlayerAccount> m_PlayerAccounts = new map<string, ref EC_PlayerAccount>; 
    
    //---------------------------
    
    static EC_MoneySystem GetInstance()
    {
        if (!Replication.IsServer())
            return null;
            
        World world = GetGame().GetWorld();
        if (!world)
            return null;
            
        return EC_MoneySystem.Cast(world.FindSystem(EC_MoneySystem));
    }
    
    //---------------------------

    override void OnInit()
    {
        EDF_DataCallbackSingle<EPF_ScriptedStateSaveData>callback(this);
        EPF_PersistentScriptedStateProxy.CreateAsync(this);
        
        SCR_BaseGameMode gameMode = SCR_BaseGameMode.Cast(GetGame().GetGameMode());
        gameMode.GetOnPlayerSpawned().Insert(OnPlayerSpawned);
    }
    
    override void OnStopped()
    {
        EPF_PersistentScriptedStateProxy.Destory(this);
    }
    
    private void OnPlayerSpawned(int playerId, IEntity player)
    {
        string uid = EC_PlayerUtils.GetPlayerUID(player);
        if (!uid) return;
        
        if (!m_PlayerAccounts.Contains(uid)) m_PlayerAccounts.Insert(uid, EC_PlayerAccount.Create());
    }

    //---------------------------
    
    EC_PlayerAccount GetPlayerAccount(IEntity player)
    {
        int playerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(player);
        string uid = GetGame().GetBackendApi().GetPlayerIdentityId(playerId );
        if (!uid || uid.IsEmpty()) return null;
        
        return m_PlayerAccounts.Get(uid);
    }
}

The EC_MoneySystem won't StructAutoCopy to EC_MoneySystemSaveData

But it works if i add this

override EPF_EReadResult ReadFrom(notnull Managed scriptedState)
{
    EC_MoneySystem moneySystem = EC_MoneySystem.Cast( scriptedState );
    m_PlayerAccounts = moneySystem.m_PlayerAccounts;
    return true;
}
    
override EPF_EApplyResult ApplyTo(notnull Managed scriptedState)
{
    EC_MoneySystem moneySystem = EC_MoneySystem.Cast( scriptedState );
    moneySystem.m_PlayerAccounts = m_PlayerAccounts;
    return true;
}

To EC_MoneySystemSaveData

Event Timeline

badcard7 created this task.Sat, Mar 29, 3:21 PM
Geez changed the task status from New to Assigned.Tue, Apr 1, 5:37 PM