1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
12 #include "sjme/nvm/rom.h"
13 #include "sjme/alloc.h"
14 #include "sjme/debug.h"
15 #include "sjme/nvm/payload.h"
16 #include "sjme/nvm/romInternal.h"
17 #include "sjme/util.h"
19 #include "sjme/cleanup.h"
21 sjme_errorCode
sjme_rom_suiteDefaultLaunch(
22 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
23 sjme_attrInNotNull sjme_rom_suite inSuite
,
24 sjme_attrOutNotNull sjme_lpstr
* outMainClass
,
25 sjme_attrOutNotNull sjme_list_sjme_lpstr
** outMainArgs
,
26 sjme_attrOutNotNull sjme_list_sjme_jint
** outById
,
27 sjme_attrOutNotNull sjme_list_sjme_lpstr
** outByName
)
31 if (inPool
== NULL
|| inSuite
== NULL
|| outMainClass
== NULL
||
32 outMainArgs
== NULL
|| outById
== NULL
|| outByName
== NULL
)
33 return SJME_ERROR_NULL_ARGUMENTS
;
35 /* Not supported internally? */
36 if (inSuite
->functions
->defaultLaunch
== NULL
)
37 return SJME_ERROR_UNSUPPORTED_OPERATION
;
40 if (sjme_error_is(error
= sjme_thread_spinLockGrab(
41 &inSuite
->common
.lock
)))
42 return sjme_error_default(error
);
45 error
= inSuite
->functions
->defaultLaunch(inPool
,
46 inSuite
, outMainClass
, outMainArgs
, outById
, outByName
);
49 if (sjme_error_is(sjme_thread_spinLockRelease(
50 &inSuite
->common
.lock
, NULL
)))
51 return sjme_error_default(error
);
57 sjme_errorCode
sjme_rom_suiteFromMerge(
58 sjme_attrInNotNull sjme_alloc_pool
* pool
,
59 sjme_attrOutNotNull sjme_rom_suite
* outSuite
,
60 sjme_attrInNotNull sjme_rom_suite
* inSuites
,
61 sjme_attrInPositive sjme_jint numInSuites
)
63 if (pool
== NULL
|| outSuite
== NULL
|| inSuites
== NULL
)
64 return SJME_ERROR_NULL_ARGUMENTS
;
67 return SJME_ERROR_INVALID_ARGUMENT
;
69 sjme_todo("Implement this?");
70 return SJME_ERROR_UNKNOWN
;
73 sjme_errorCode
sjme_rom_suiteFromPayload(
74 sjme_attrInNotNull sjme_alloc_pool
* pool
,
75 sjme_attrOutNotNull sjme_rom_suite
* outSuite
,
76 sjme_attrInNotNull
const sjme_payload_config
* payloadConfig
)
78 sjme_jint i
, numActive
, numLibraries
;
80 if (pool
== NULL
|| outSuite
== NULL
|| payloadConfig
== NULL
)
81 return SJME_ERROR_NULL_ARGUMENTS
;
83 /* Count the number of active ROMs. */
86 for (i
= 0; i
< SJME_NVM_PAYLOAD_MAX_ROMS
; i
++)
87 if (payloadConfig
->roms
[i
].isActive
)
92 /* Anything that is a library we need to build a container. */
93 if (payloadConfig
->roms
[i
].isLibrary
)
97 /* If there is nothing active then nothing needs to be done. */
101 return SJME_ERROR_NONE
;
104 sjme_todo("Implement this?");
105 return SJME_ERROR_UNKNOWN
;
108 sjme_errorCode
sjme_rom_suiteLibraries(
109 sjme_attrInNotNull sjme_rom_suite inSuite
,
110 sjme_attrOutNotNull sjme_list_sjme_rom_library
** outLibs
)
112 sjme_rom_suiteCache
* cache
;
113 sjme_rom_suiteListLibrariesFunc listFunc
;
114 sjme_list_sjme_rom_library
* result
;
115 sjme_errorCode error
;
118 if (inSuite
== NULL
|| outLibs
== NULL
)
119 return SJME_ERROR_NULL_ARGUMENTS
;
121 /* Must be a valid cache. */
122 cache
= &inSuite
->cache
;
123 if (cache
->common
.allocPool
== NULL
)
124 return SJME_ERROR_ILLEGAL_STATE
;
126 /* Has this been processed already? */
127 if (cache
->libraries
!= NULL
)
130 sjme_message("Using existing cache: %p", cache
->libraries
);
132 *outLibs
= cache
->libraries
;
133 return SJME_ERROR_NONE
;
136 /* Check list function. */
137 listFunc
= inSuite
->functions
->list
;
138 if (listFunc
== NULL
)
139 return SJME_ERROR_NOT_IMPLEMENTED
;
142 if (sjme_error_is(error
= sjme_thread_spinLockGrab(
143 &inSuite
->common
.lock
)))
144 return sjme_error_default(error
);
146 /* Call the list function. */
148 if (sjme_error_is(error
= listFunc(inSuite
,
149 &result
)) || result
== NULL
)
152 /* Store it within the cache. */
153 cache
->libraries
= result
;
155 /* All of these must be valid libraries. */
156 for (i
= 0, n
= result
->length
; i
< n
; i
++)
157 if (result
->elements
[i
] == NULL
)
159 error
= SJME_ERROR_LIBRARY_NOT_FOUND
;
160 goto fail_missingLib
;
164 if (sjme_error_is(error
= sjme_thread_spinLockRelease(
165 &inSuite
->common
.lock
, NULL
)))
166 return sjme_error_default(error
);
170 return SJME_ERROR_NONE
;
174 /* Release lock before failing. */
175 if (sjme_error_is(sjme_thread_spinLockRelease(
176 &inSuite
->common
.lock
, NULL
)))
177 return sjme_error_default(error
);
179 return sjme_error_default(error
);
182 sjme_errorCode
sjme_rom_suiteNew(
183 sjme_attrInNotNull sjme_alloc_pool
* pool
,
184 sjme_attrOutNotNull sjme_rom_suite
* outSuite
,
185 sjme_attrInNullable sjme_pointer data
,
186 sjme_attrInNotNull
const sjme_rom_suiteFunctions
* inFunctions
,
187 sjme_attrInNullable
const sjme_frontEnd
* copyFrontEnd
)
189 sjme_rom_suite result
;
190 sjme_errorCode error
;
192 if (pool
== NULL
|| outSuite
== NULL
|| inFunctions
== NULL
)
193 return SJME_ERROR_NULL_ARGUMENTS
;
195 /* These functions are required. */
196 if (inFunctions
->init
== NULL
||
197 inFunctions
->libraryId
== NULL
||
198 inFunctions
->list
== NULL
||
199 inFunctions
->loadLibrary
== NULL
)
200 return SJME_ERROR_NOT_IMPLEMENTED
;
202 /* Allocate resultant suite. */
204 if (sjme_error_is(error
= sjme_nvm_alloc(pool
,
205 sizeof(*result
), SJME_NVM_STRUCT_ROM_SUITE
,
206 SJME_AS_NVM_COMMONP(&result
))) || result
== NULL
)
210 result
->cache
.common
.allocPool
= pool
;
211 result
->functions
= inFunctions
;
213 /* Copy front end data? */
214 if (copyFrontEnd
!= NULL
)
215 memmove(&result
->common
.frontEnd
, copyFrontEnd
,
216 sizeof(*copyFrontEnd
));
218 /* Call initializer. */
219 if (sjme_error_is(error
= inFunctions
->init(result
, data
)))
224 return SJME_ERROR_NONE
;
229 sjme_closeable_close(SJME_AS_CLOSEABLE(result
));
231 return sjme_error_default(error
);