summaryrefslogblamecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pstate.h
blob: 71db3b97bb6936be582e2f15ac908d8e71b393d6 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                               



                 



                  
                   
                    
                   
 
                
                 
                 
 



                                                                                           
                
                     

       
 

                         
                                                                          
                                                                                                 
                  
                                                 
                                                                                          

                  









                                                                           

          

                                 
         



                                                                                      
 
                        


                                                         
 
                                                                                                 

                                                                        
                  
                                       
                                                
                                                   
          
 

                      
                                                    
 
                                                                                       

                                                                                                               
 

                                                                                                                              
 







                                                                             
                                           
                                         

                                               
                                            
                                          
          
 
                                    
 
                                                                                                                               
                                                                          
         
                                                                      
         
 

                                                                                                                                                     
         
                                                                          
         
 

                                                                                                   
         
                                                                        
         
 

                                                                                      
         






                                                                                     

         

                                                                                                                               
                                                                   




                                         
                                                         




                                         
                                                          







                                                 
                                                





                                                    
                                                


                                                      
 



                                                            
                                          

                           
 

          
        
                               

                                 

  

                                                                                                              
                                                     


                                            
 
                   
 
                   
// license:GPL-2.0+
// copyright-holders:Couriersud

#ifndef PSTATE_H_
#define PSTATE_H_

///
/// \file pstate.h
///

#include "palloc.h"
#include "pstring.h"
#include "ptypes.h"

#include <array>
#include <memory>
#include <vector>

// ----------------------------------------------------------------------------------------
// state saving ...
// ----------------------------------------------------------------------------------------

namespace plib {
class state_manager_t
{
public:

	struct datatype_t
	{
		datatype_t(std::size_t bsize, bool bintegral, bool bfloat)
		: m_size(bsize), m_is_integral(bintegral), m_is_float(bfloat), m_is_custom(false)
		{}
		explicit datatype_t(bool bcustom)
		: m_size(0), m_is_integral(false), m_is_float(false), m_is_custom(bcustom)
		{}

		std::size_t size() const noexcept { return m_size; }
		bool is_integral() const noexcept { return m_is_integral; }
		bool is_float()    const noexcept { return m_is_float; }
		bool is_custom()   const noexcept { return m_is_custom; }

	private:
		std::size_t m_size;
		bool m_is_integral;
		bool m_is_float;
		bool m_is_custom;
	};

	template<typename T>
	static datatype_t dtype()
	{
		return datatype_t(sizeof(T),
				plib::is_integral<T>::value || std::is_enum<T>::value,
				std::is_floating_point<T>::value);
	}

	class callback_t
	{
	public:
		using list_t = std::vector<callback_t *>;

		virtual void register_state(state_manager_t &manager, const pstring &module) = 0;
		virtual void on_pre_save(state_manager_t &manager) = 0;
		virtual void on_post_load(state_manager_t &manager) = 0;
	protected:
		callback_t() = default;
		virtual ~callback_t() = default;
		COPYASSIGNMOVE(callback_t, default)
	};

	struct entry_t
	{
		using list_t = std::vector<entry_t>;

		entry_t(const pstring &stname, const datatype_t &dt, const void *owner,
				const std::size_t count, void *ptr)
		: m_name(stname), m_dt(dt), m_owner(owner), m_callback(nullptr), m_count(count), m_ptr(ptr) { }

		entry_t(const pstring &stname, const void *owner, callback_t *callback)
		: m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { }

		pstring name() const noexcept { return m_name; }
		datatype_t dt() const noexcept { return m_dt; }
		const void * owner() const noexcept { return m_owner; }
		callback_t * callback() const noexcept { return m_callback; }
		std::size_t count() const noexcept { return m_count; }
		void * ptr() const noexcept { return m_ptr; }

	private:
		pstring             m_name;
		datatype_t          m_dt;
		const void *        m_owner;
		callback_t *        m_callback;
		std::size_t         m_count;
		void *              m_ptr;
	};

	state_manager_t() = default;

	template<typename C> //, typename std::enable_if<std::is_integral<C>::value || std::is_floating_point<C>::value>::type>
	void save_item(const void *owner, C &state, const pstring &stname)
	{
		save_state_ptr( owner, stname, dtype<C>(), 1, &state);
	}

	template<typename C, std::size_t N>
	void save_item(const void *owner, C (&state)[N], const pstring &stname) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
	{
		save_state_ptr(owner, stname, dtype<C>(), N, &(state[0]));
	}

	template<typename C>
	void save_item(const void *owner, C *state, const pstring &stname, const std::size_t count)
	{
		save_state_ptr(owner, stname, dtype<C>(), count, state);
	}

	template<typename C, typename A>
	void save_item(const void *owner, std::vector<C, A> &v, const pstring &stname)
	{
		save_state_ptr(owner, stname, dtype<C>(), v.size(), v.data());
	}

	template<typename C, std::size_t N>
	void save_item(const void *owner, std::array<C, N> &a, const pstring &stname)
	{
		save_state_ptr(owner, stname, dtype<C>(), N, a.data());
	}

	void save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr)
	{
		m_save.emplace_back(stname, dt, owner, count, ptr);
	}

	void pre_save()
	{
		for (auto & s : m_custom)
			s.callback()->on_pre_save(*this);
	}

	void post_load()
	{
		for (auto & s : m_custom)
			s.callback()->on_post_load(*this);
	}

	void remove_save_items(const void *owner)
	{
		auto i = m_save.end();
		while (i != m_save.begin())
		{
			i--;
			if (i->owner() == owner)
				i = m_save.erase(i);
		}
		i = m_custom.end();
		while (i > m_custom.begin())
		{
			i--;
			if (i->owner() == owner)
				i = m_custom.erase(i);
		}
	}

	const std::vector<const entry_t *> save_list() const
	{
		std::vector<const entry_t *> ret;
		for (auto &i : m_save)
			ret.push_back(&i);
		return ret;
	}

protected:

private:
	entry_t::list_t m_save;
	entry_t::list_t m_custom;

};

template<> inline void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname)
{
	m_custom.emplace_back(stname, owner, &state);
	state.register_state(*this, stname);
}


} // namespace plib

#endif // PSTATE_H_